【问题标题】:Awaiting a coroutine inside of a Class while event_loop is already running在 event_loop 已经运行时等待 Class 内的协程
【发布时间】:2018-03-20 12:34:13
【问题描述】:

我对 asyncio 有一个问题,我无法真正解决问题。

以这个工作示例(使用 Python 3.6+,因为字符串插值)

import asyncio
import aiohttp
import async_timeout
import json


async def fetch(session, url):
    async with async_timeout.timeout(10):
        async with session.get(url) as response:
            return await response.text()


async def get_bittrex_marketsummary(currency_pair):
    url = f'https://bittrex.com/api/v1.1/public/getmarketsummary?market={currency_pair}'
    async with aiohttp.ClientSession() as session:
        response = await fetch(session, url)
    return json.loads(response)


class MyCryptoCurrency:
    def __init__(self):
        self.currency = "BTC-ETH"
        self.last_price = None
        asyncio.ensure_future(self.get_last_price())

    async def get_last_price(self):
        self.last_price = await get_bittrex_marketsummary(self.currency)


async def main():
    eth = MyCryptoCurrency()
    print(eth.last_price)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

虽然它运行并且不会抛出任何异常,但它不会从 api 请求中获得结果,所以......不起作用:P

如果我尝试使用 f.e. loop.run_until_complete(get_bittrex_marketsummary()) 我得到“事件循环已经在运行”错误 - 这是有道理的。

任何提示如何正确解决这个问题?

提前谢谢!

【问题讨论】:

标签: python-3.x python-asyncio


【解决方案1】:

好的,在 freenode 上的#python 频道中讨论了这个之后,我得到了答案“不要在 __init__ 中执行异步 I/O”,所以这是工作版本:

import asyncio
import aiohttp
import async_timeout
import json


async def fetch(session, url):
    async with async_timeout.timeout(10):
        async with session.get(url) as response:
            return await response.text()


async def get_bittrex_marketsummary(currency_pair):
    url = f'https://bittrex.com/api/v1.1/public/getmarketsummary?market={currency_pair}'
    async with aiohttp.ClientSession() as session:
        response = await fetch(session, url)
    return json.loads(response)


class MyCryptoCurrency:
    def __init__(self):
        self.currency = "BTC-ETH"
        self.last_price = None

    async def get_last_price(self):
        self.last_price = await get_bittrex_marketsummary(self.currency)


async def main():
    eth = MyCryptoCurrency()
    await eth.get_last_price()
    print(eth.last_price)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多