【问题标题】:What does the "yield from" syntax do in asyncio and how is it different from "await"“yield from”语法在 asyncio 中有什么作用,它与“await”有何不同
【发布时间】:2017-10-30 06:25:37
【问题描述】:

从编写过异步代码但希望更好地了解内部工作原理的人的角度来看,yield fromawait 是什么以及它们对允许异步代码有何用处?

有一个highly upvoted 问题询问yield from 语法和one explaining async and await 的用法,但两者都深入探讨了不同的主题,并不是对底层代码及其如何适应的真正简明解释异步。

【问题讨论】:

  • & asyncio.coroutine 表达。我想我不太确定这个问题在问什么,因为这个例子似乎很好地解释了它。你能说得更具体点吗?
  • @mgilson 它涉及awaityield from 的关系,但实际上不是yield from 的作用
  • 它们是一样的,除了await 更多recent 并且看起来好多了

标签: python async-await generator python-asyncio coroutine


【解决方案1】:

简答:

yield from 是等待 asyncio 协程的老方法。

await 是一种等待 asyncio 协程的现代方式。

详细回答:

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

从 Python 3.4 开始,asyncio 模块被添加到标准库中。它使我们能够编写清晰易懂的异步代码。虽然技术上 asyncio 的协程可以以不同的方式实现,但在 asyncio 中它们是使用生成器实现的(您可以关注 excellent video,其中显示了如何使用生成器来实现协程)。 @asyncio.coroutine 是一种从生成器生成协程的方法,yield from 是一种等待协程的方法——只是实现的细节。

这就是yield from 开始被用于两个“不同的事物”的原因。

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

如果您使用的是 Python 3.5+,则可以忘记将 yield from 用于 asyncio 的协程,而使用 await 来处理它。

【讨论】:

  • 圣洁的 c**p,@mikhail,我希望我在浪费大量时间与 yield from@asyncio.coroutine 之前已经阅读了这篇文章!然后我读了async defawait,然后我说“嗯,我想知道有什么区别”。我希望在PEP 3156... 中更清楚地说明这一点
  • 谢谢。 “除了生成器”应该更明确一点,你在技术上是正确的 def foo(): x = yield 的实例是 generator 类型(出于历史原因),但通俗地说它是一个“Beazly-style”协程而不是真正的人想到说生成器。
  • @timgeb 谢谢,已更正。我想现在应该没问题:)
  • 我个人认为这是整个 Python 历史上最令人困惑的问题/文档。使用“async def”和“await”,它会好 10 倍,但它仍然是 Python 最令人困惑的特性。我不明白他们是如何让“yield from”正式发布的......如果我现在要学习一门新语言,我会因为这种语法而跳过 Python。
  • @Jay await(以及它的旧版本yield from)将在不阻塞事件循环的情况下“阻塞”本地执行流。要在不阻塞本地执行流程的情况下运行任务,您需要创建 asyncio 的任务 - read about it here
猜你喜欢
  • 2018-02-22
  • 1970-01-01
  • 2014-01-10
  • 2016-06-01
  • 2014-04-22
  • 2016-01-07
  • 2020-05-30
  • 1970-01-01
  • 2018-08-03
相关资源
最近更新 更多