What does the “yield from” syntax do in asyncio and how is it different from “await”
从编写了异步代码但希望更好地理解内部工作的人的角度来看,yield from、await是什么?这些对于允许异步代码有何帮助?
关于yield from语法的用法,有一个非常乐观的问题,一个解释async和await,但都深入讨论了不同的主题,并不是对底层代码以及它如何与asyncio相适应的一个简明解释。
- 第二个问题似乎给了你一个非常直接的解释,说明了如何使用async和await更简洁地表达你过去需要yield from和asyncio.coroutine表达的内容。我想我不太确定这个问题是怎么问的,因为这个例子似乎能很好地解释它。你能更具体一点吗?
- @mgilson研究了await与yield from的关系,但实际上不是yield from的作用。
- 它们是一样的,只是await比较新,看起来好多了。
型
简短回答:
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)开始,coroutines有了新的语法。现在可以用async def定义协同程序,并使用await表达式等待它。它不仅写得更短,而且更清楚地理解我们使用的是Asyncio的协程。
如果您使用的是python 3.5+,那么您可以忘记将yield from用于Asyncio的协程,并将await用于它。
- 天哪,米哈伊尔,我真希望我能在浪费这么多时间和伊多克斯1〔0〕和伊多克斯1〔1〕在一起之前读完这本书!然后我读了《江户记》(2)和《江户记》(3),"嗯,我想知道有什么区别"。我希望这在PEP 3156中更清楚…
- "如果您使用的是python 3.5+,那么除了生成器之外,您可以忘记使用任何东西的yield,而使用wait for coroutines。"<-您不只是指在asyncio如何定义它们的狭义上下文中的coroutines吗?如果我想把控制权交给一个自编的协同程序foo,它使用got_value = yield,你应该手动将值发送给它,我仍然需要使用yield from foo(),对吗?
- @Timgeb是的,你说得对:我指的只是异步协程。我将编辑答案。
- 谢谢。"除了"发电机"应该更明确一点,从技术上讲,你是正确的,def foo(): x = yield的一个实例是generator类型(出于历史原因),但通俗地说,它是一个"Beazly风格"的协同程序,而不是人们在说发电机时所想的。
- @Timgeb谢谢,纠正。我想现在应该可以了:)
- 我个人认为这是整个Python历史上最令人困惑的问题/文档。有了"async def"和"wait",它的性能提高了10倍,但这仍然是Python最令人困惑的特性。我不知道他们是如何从官方发布的"屈服"中…如果我现在学习一种新的语言,我将跳过Python,仅仅因为这个语法。