假设我有一个在内部使用异步循环并且没有异步接口(interface)的类:
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
接口(interface)就不会有问题:asyncio.gather
可以帮助我。不支持both interfaces真的没有别的办法吗? ?快点!它会让你因为一次 asyncio 使用而改变你的所有项目。告诉我这不是真的。
最佳答案
Come on! It makes you change all your project because of one asyncio usage. Tell me this is not true.
这是真的
使用 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
。
关于python - async - sync - 一个 python 事件循环中的异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45213133/