生成器函数和异步生成器函数的目的有哪些区别?

8
在Python中,异步生成器函数是协程,而生成器函数也是协程。
生成器函数和异步生成器函数的目的有什么区别?
谢谢。

3
CV选手,如果问题太过宽泛,那么我所提供的答案长度也无法满足要求。请不要盲目投票。我的翻译是否通顺易懂,请您自行判断。 - Dimitris Fasarakis Hilliard
1个回答

10

PEP 525 -- 异步生成器的目的与PEP 255 -- 简单生成器相似,其引入了生成器。它主要旨在使事情更易于实现,但在不同的领域(异步)中。PEP 525的定义如下:

本质上,针对异步执行情况的 PEP 255 的目标和基本原理同样适用于本提案。

简而言之,它使编写支持 异步迭代协议 的对象变得容易。就像 生成器 对于 迭代器协议 所做的一样。

不需要定义实现__aiter__和__anext__的对象,您可以创建一个异步生成器来完成这个看似神奇的工作。这类似于生成器对迭代器协议所做的工作;您只需创建一个生成器,而不必为对象实现__iter__和__next__。
PEP 525的理论基础中很好地阐述了这一点,还包括一个漂亮的示例,展示了在使用异步生成器时节省的代码量。
除了代码长度的节省外,异步生成器的性能也要好得多:
“性能是该提案的另一个重点:在我们测试参考实现时,异步生成器比作为异步迭代器实现的等效方案快2倍。”

这里为了增加一些术语,因为有时候术语很难跟上:

  • 生成器: 包含一个或多个yield表达式的def函数。
  • 基于生成器的协程: 由types.coroutine包装的生成器(def + yield)。如果您需要将其视为协程对象,则需要在其中包装types.coroutine
  • 异步生成器: 包含一个或多个yield表达式的async def函数。这些也可以包含await表达式。
  • 协程: 没有零个或多个await和没有yieldasync def

谢谢。在“异步生成器:包含yield表达式的async def函数”中,您是指await而不是yield吗? - Tim
@Tim 不不,如果你在一个async def中只有一个await,那么你会获得一个协程。而在async def中存在yield才使它成为异步生成器 :-). - Dimitris Fasarakis Hilliard
就它们的目的而言,“异步生成器”、“基于生成器的协程”和“生成器”有什么区别?(不仅仅是它们的定义方式,您已经描述过了) - Tim
4
生成器被用作数据的生产者(它们通过 yield 语句产出值)。基于生成器的协程则被用作数据的消费者(你可以使用 .send 方法向其发送值,或使用 yield from 向其子生成器发送值)。异步生成器是异步数据的生产者(而协程则是异步数据的消费者)。 - Dimitris Fasarakis Hilliard
“没有零或更多”这个措辞有些令人困惑,它是否意味着必须没有产量和等待? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接