python - 异步设计/实现

标签 python async-await python-asyncio

我最近开始用 Python 实现一些异步代码,我对设计和实现有一些疑问。 例如,如果我必须做一些事情,让我将同步代码作为非async函数调用,并且我只有一个async函数,返回协程被认为是坏习惯还是坏设计? 让我用一些代码更好地解释一下:

def my_async_function():
    #some sync code
    return async_code()

而不是:

async def my_async_function():
    #some sync code
    return await async_code()

您认为第一个版本可能隐藏一些问题吗?
或者总的来说,每一条建议都会受到赞赏,因为我对这种风格的代码很陌生。
P.S.:抱歉我的英语不好,我希望它是可以理解的。

最佳答案

两种变体都是完全正确的,但如果有疑问,请选择第二个。它将使调用者清楚地知道他们正在处理一个协程,并且只是一个协程。

两者之间存在技术差异,但只有当调用者不立即等待时,这种差异才会变得明显。考虑以下代码:

aw = my_async_function()
# ... do something here ...
result = await aw

在您的第一个示例中,“某些同步代码”将在您调用该函数后立即运行,因此如果它有副作用,它们将在“在此处执行某些操作”中可见。在第二个示例中,仅调用 my_async_function() 是完全无副作用的,它仅创建协程对象。在该变体中,“某些同步代码”仅在 await aw 时执行,即“在此处执行某些操作”已经运行之后。

将协程定义为 async def 可以向调用者保证,在实际等待协程结果之前不会运行任何同步代码,这可能是一个重要的保证。即使该函数不是异步并且仅返回一个可等待的,也最好表现得就像它支持这种保证,至少在调用者可以观察到的范围内它。

一个不遵守此原则的著名示例是 run_in_executor它立即将可调用对象提交到线程池。因此,run_in_executor 永远不能成为一个实际的协程,因为这会破坏调用它而不费心 await 的代码(或者出于某种原因只在稍后等待的代码) .

关于python - 异步设计/实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56038047/

相关文章:

python - sqlalchemy 查询持续时间日志记录

python - 安装osmnx时出错(必须指定A GDAL API版本)问题

c# - 异步发送电子邮件和处理

c# - 我可以指定在 await continuation 完成后我希望保留哪些变量吗?

python - Python 中的 ZeroMQ N 到 N 异步模式

python - 我可以将异常作为参数传递给 python 中的函数吗?

python - 如何结合tkinter和turtle?

c# - 使用任务来避免多次调用昂贵的操作并缓存其结果

python - 如何在Python中选择异步或同步方法变体?

python - 如何制作一组既可以同步又可以异步使用的函数?