为什么基于Generator的协程会消耗、异步生成器是异步数据生产者,而协程是异步数据使用者?

2024-04-25 14:09:37 发布

您现在位置:Python中文网/ 问答频道 /正文

作者:Jim Fasarakis Hilliard:

Generators: def functions that contain one or more yield expressions.

Generators are used as data producers (they yield values).

我能理解。在

Generator-based coroutine: A generator (def + yield) that is wrapped by types.coroutine. You need to wrap it in types.coroutine if you need it to be considered a coroutine object.

Generator-based coroutines are used as consumers (you .send values to them or to a sub-generator they yield from).

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

Asynchronous Generator: async def functions that contain a one or more yield expressions. These can also contain await expressions.

Asynchronous generators are asynchronous data producers.

“异步数据生产者”是什么意思?在

Coroutine: async def without zero or more awaits and no yields.

coroutines are asynchronous data consumers.

“异步数据消费者”是什么意思?在

谢谢。在


Tags: ortodatathatdefmorefunctionsgenerator
1条回答
网友
1楼 · 发布于 2024-04-25 14:09:37

在python中,生成器现在以多种方式使用。生成器的最初目的是挂起执行,然后yield一个值返回给调用者。然后,调用者可以稍后调用next来恢复生成器。因此,生成器就是数据生产者。在

现在上面版本的生成器只允许通过yield语句返回数据。现在,要使函数成为协同程序,它还应该接受调用者的值。因此,python2.5中引入了PEP 342增强生成器,以便它们可以作为完整的协程函数。这允许调用者向生成器发送值。在

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

现在的问题是生成器在两种不同的环境中使用。作为迭代器和协同程序。如果生成器可以显式地定义为协程,那就更好了。因此,Python3.5中的PEP 492 introduced ^{} and ^{}关键字。因此,任何用作协同程序的生成器都由async关键字表示。python3.5中的协同程序可以使用await关键字,而不是yield from。请注意,从Python3.5开始,协同程序是一种不同的类型!!在

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

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

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

相关问题 更多 >

    热门问题