假设我有一个类,它在内部使用 asyncio 循环并且没有异步接口:
class Fetcher:
_loop = None
def get_result(...):
"""
After 3 nested sync calls async tasks are finally called with *run_until_complete*
"""
...
我在内部使用了 asyncio 的所有优点,而不必在外部代码中关心它。
但是我想在一个事件循环中调用 3 个Fetcher
实例。如果我有async def
界面,就不会有问题:asyncio.gather
可以帮助我。如果不同时支持这两个接口,真的没有其他方法可以做到这一点吗?加油!它使你改变你的所有项目,因为你一个异步用法。告诉我这不是真的。
加油!它使您因为一个异步而更改所有项目 用法。告诉我这不是真的。
是真的
使用await
关键字的整个想法是从代码的不同位置在一个事件循环中执行并发作业(这是常规函数代码无法做到的(。
asyncio
- 不是一些实用程序,而是编写异步程序的整个风格。
另一方面,Python 非常灵活,因此您仍然可以尝试使用 asyncio 进行隐藏。如果您确实想获得 3 个 Fetcher 实例的同步结果,您可以执行以下操作:
import asyncio
def sync_exec(coro):
loop = asyncio.get_event_loop()
return loop.run_until_complete(coro)
class Fetcher:
async def async_get_result(self):
# async interface:
async def async_job():
await asyncio.sleep(1)
return id(self)
return (await async_job())
def get_result(self):
# sync interface:
return sync_exec(self.async_get_result())
@classmethod
def get_results(cls, *fetchers):
# sync interface multiple:
return sync_exec(
asyncio.gather(*[fetcher.async_get_result() for fetcher in fetchers])
)
# single sync get_result:
f1 = Fetcher()
print('Result: ', f1.get_result())
# multiple sync get_result:
f2 = Fetcher()
f3 = Fetcher()
print('Results: ', Fetcher.get_results(f1, f2, f3))
输出:
Result: 2504097887120
Results: [2504097887120, 2504104854416, 2504104854136]
但是,再说一次,如果你继续以这种方式编写代码,你真的会后悔的,相信我。如果要充分利用异步编程 - 请显式使用coroutines
和await
。