为什么基于生成器的协程使用异步数据生成者,而协程使用异步数据使用者?



摘自Jim Fasarakis Hilliard的评论:

生成器:def包含一个或多个yield表达式的函数。

生成器用作数据生产者(它们yield值)。

我能理解。

基于生成器的协程:由types.coroutine包装的生成器 (def+yield)。你需要把它包裹起来types.coroutine是否需要将其视为协程对象。

基于生成器的协程用作使用者(.send值 他们或他们yield from的子生成器)。

"消费者(你.send他们或他们yield from的子生成器的价值)"是什么意思?

异步生成器:async def包含一个或多个yield表达式的函数。这些还可以包含await表达式。

异步生成器是异步数据生成器。

"异步数据生成者"是什么意思?

协程:没有零个或多个awaits 且没有yields 的async def

协程是异步数据使用者

"异步数据使用者"是什么意思?

谢谢。

在python中,生成器现在以多种不同的方式使用。生成器的最初目的是暂停执行,然后将值yield回调用方。然后,调用方可以稍后调用 next 以恢复生成器。因此,生成器是数据生产者。

现在上述版本的生成器只允许通过yield语句返回数据。现在,要使函数成为协程,它还应该接受来自调用方的值。因此,PEP 342在 python 2.5 中引入,以增强生成器,以便它们可以充当完整的协程。这允许调用方将值发送到生成器。

现在的新问题是,当生成器被重构并且您希望将其部分操作委托给子生成器时,您需要显式调用子生成器作为迭代器,传播调用方发送的数据并处理异常。为了简化子生成器的操作,PEP 380 中定义了一个新的操作yield from作为 python 3.3 的一部分yield from在语法上比普通的屈服语法要多得多。在一个完美的世界里,可能会使用一个新的关键字。

现在的问题是发电机是在两种不同的环境中使用的。作为迭代器和协程。如果可以将生成器显式定义为协程,那就更好了。因此,PEP 492在 Python 3.5 中引入了asyncawait关键字。因此,任何用作协程的生成器都由async关键字指示。Python 3.5 中的协程可以使用await关键字代替yield from。请注意,从 python 3.5 开始,协程是一种不同的类型!!

现在假设您有一个具有defyield的生成器函数。可以使用types.coroutine修饰器将现有生成器类型转换为协程类型。这些是可以通过send()接受值并使用yield from将其委托给子生成器的消费者。

在 python 3.5 中,您可以使用async来指示函数是协程类型。这样的函数可以包含普通yieldawait。它们不能包含yield from(因为await替换要素)。当一个协程包含普通yield时,它们是生成器调用链中最低的,因此称为异步数据生产者。

任何没有纯yield的协程都将是数据使用者,因为它必须通过await调用另一个协程才能获取异步数据。

最新更新