为什么基于生成器的协同程序消耗,异步生成器异步数据生成器和协同程序异步数据使用者?

时间:2017-10-19 02:38:53

标签: python python-3.x asynchronous generator coroutine

来自a comment的Jim Fasarakis Hilliard:

  

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

     

生成器用作数据生成器(它们是yield个值)。

我能理解。

  

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

     

基于生成器的协同程序用作使用者(您.send的值为yield from   他们或他们.send)的子发电机。

“消费者(您yield from对他们或他们async def)的子发电机的价值是什么意思?”

  

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

     

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

“异步数据生成器”是什么意思?

  

协程:await没有零个或多个yield s且没有<property> <name> yarn.nodemanager.disk-health-checker.max-disk-utilization-per-disk-percentage </name> <value>90.0</value> <source>yarn-default.xml</source> </property> 个。

     

协同程序是异步数据使用者

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

感谢。

1 个答案:

答案 0 :(得分:3)

在python中,现在可以通过多种方式使用生成器。 生成器的最初目的是暂停执行,然后yield将值返回给调用者。然后呼叫者可以稍后呼叫以恢复发电机。因此,发电机是数据生产者。

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

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

现在的问题是发电机在两种不同的环境中使用。作为迭代器和协程。如果可以将生成器明确定义为协程,那会更好。因此,Python 3.5中的PEP 492 introduced async and await个关键字。因此,任何用作协程的生成器都由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调用另一个协程来获取异步数据。