"yield from"语法在asyncio中的作用是什么?它与"await"有什么不同?

Azs*_*sgy 32 python generator coroutine async-await python-asyncio

从谁写ASYNCIO代码,但正在寻求更好地理解内部工作的人的角度来看,是什么yield from,await以及如何允许异步代码这些有用吗?

有一个高度赞成的问题询问yield from语法的用法和解释异步和等待的问题,但两者都深入讨论了不同的主题,并不是对底层代码及其如何适应asyncio的简明解释.

Mik*_*mov 43

简短回答:

yield from 是一种等待asyncio的协同程序的老方法.

await 是一种等待asyncio协同程序的现代方式.

详细解答:

Python有生成器 - 一种特殊的函数,它产生一系列结果而不是单个值.从Python 3.3 yield from表达式开始添加.它允许一个生成器将其部分操作委托给另一个生成器.

从Python 3.4开始,asyncio模块被添加到标准库中.它允许我们编写清晰易懂的异步代码.虽然技术上asyncio的协同程序可以以不同的方式实现,asyncio但它们是使用生成器实现的(您可以观看优秀的视频,其中显示了如何使用生成器来实现协同程序).@asyncio.coroutine是一种从发电机制作协程yield from的方法,是一种等待协程的方法 - 只是实施细节.

这就是yield from开始用于两个"不同的事情"的情况.

从Python 3.5开始(参见PEP 492),协同程序获得了新的语法.现在,您可以async def使用await表达式定义协同程序并等待它.它不仅写得更短,而且更清楚地理解我们使用asyncio的协同程序.

如果您使用的是Python 3.5+,则可以忘记使用yield fromasyncio的协同程序并使用await它.

  • “如果你使用的是 Python 3.5+,你可以忘记对除生成器以外的任何东西使用 yield from 而对协程使用 await。” <- 你不是说在 `asyncio` 如何定义它们的狭隘上下文中的协程吗?如果我想将控制权传递给使用 `got_value = yield` 的自己编写的协程 `foo`,我仍然必须使用 `yield from foo()`,您应该手动将值发送到其中,对吗? (4认同)
  • 天哪,@mikhail,我希望在浪费这么多时间在“yield from”和“@asyncio.coroutine”上之前读过这篇文章!然后我读了 `async def` 和 `await`,然后我就“嗯,我想知道有什么区别”。我希望在 [PEP 3156](https://www.python.org/dev/peps/pep-3156) 中更清楚地说明这一点... (2认同)
  • @Jay `await` (以及它的旧版本 `yield from`)将“阻塞”本地执行流,而不阻塞事件循环。要在不阻塞本地执行流的情况下运行任务,您需要创建 asyncio 的任务 - [在此处阅读](/sf/answers/2614189511/)。 (2认同)