Mar*_*ses 12 python async-await python-asyncio
我所有的代码都是在没有考虑 asyncio 的情况下编写的;但是,我使用一个异步函数(由另一位开发人员编写;出于我的目的,它是一个黑匣子)。我们就这样称呼吧func_1。我需要从另一个函数中调用这个函数,调用它func_2(它本身可以在任意长的函数链中调用func_3,func_4等等......)。
由于func_1是异步的,我需要等待它,但由于我在 中调用它func_2,所以我也需要进行func_2异步(我不能在非异步函数中等待)。这样的情况一直持续下去;我需要将整个函数链func_2, func_3,转换func_4为异步函数。
有办法避免这种情况吗?我只想调用func_1,等待它完成,然后在我的正常 python 代码的其余部分中使用结果。我可以创建一个包装器func_1来允许这样做吗?
我想要的基本上是以下内容,但不起作用:
# This is the function defined by someone else
async def func_1(*args):
return something(*args)
# This is my wrapper
def func_1_wrapper(*args):
return await func_1(*args)
# So that I can call it like normal within the rest of my code
def func_2(*args):
# do something
a = func_1_wrapper(*args)
# do something else
Run Code Online (Sandbox Code Playgroud)
小智 4
本质上,您想要启动一个事件循环(异步代码的“引擎”),将函数提交到事件循环,然后等待事件循环执行该函数。
\n一种方法是asyncio.run(func_1()),但如果代码中的其他内容已经启动了事件循环,或者如果您在多线程上下文中运行它,则可能会遇到问题。
处理这些边缘情况的一个简单方法是使用一个类似的库,asgiref.sync它允许您执行以下操作:func_1_sync = async_to_sync(func_1)然后func_1_sync()直接从同步函数调用。这是他们的 pypi 页面的片段:
\n\n这些[辅助函数]允许您包装或装饰异步或同步函数,以便从其他样式调用它们(因此您可以从同步线程调用异步函数,反之亦然)。
\n尤其:
\n当在主线程\xe2\x80\x99s 事件循环上调用异步函数时,AsyncToSync 让同步子线程停止并等待,然后在异步函数完成时将控制返回给线程。\nSyncToAsync 让异步代码调用同步函数,在线程池中运行,并在同步函数完成时将控制权返回给异步协程。其想法是让从异步代码调用同步 API 和从同步代码调用异步 API 变得更容易,以便更轻松地将代码从一种样式转换为另一种样式。
\n
另一个执行此操作的库是syncer:
\n\n\n有时(主要是在测试中)我们需要将异步函数转换为正常的同步函数并同步运行它们。它可以通过 ayncio.get_event_loop().run_until_complete() 完成,但它\xe2\x80\x99s 相当\nlong\xe2\x80\xa6
\nSyncer 使这种转换变得容易。
\n\n
\n- 将协程函数(由 aync def 定义)转换为普通(同步)函数
\n- 同步运行协程
\n- 支持 async def 和装饰器 (@asyncio.coroutine) 风格
\n
| 归档时间: |
|
| 查看次数: |
11803 次 |
| 最近记录: |