基于生成器的协程与原生协程

Generator-based coroutine versus native coroutine

我刚刚读到 PEP0492 谈论协程的新方法,但 PEP 未能让我理解基于生成器的协程和本机协程之间的区别。谁能告诉我区别(也许有例子)?

据我了解,他们使用了不同的词(yield/yield 和 await/async/yield)。我知道在原生协程结束时预期会产生收益,但这也适用于基于生成器的协程。

嗯,通常编写协程的方式涉及回调。尽管回调最初可能很方便,但在我看来,它们会导致代码非常复杂和复杂,至少可以说这不是 pythonic。此外,yield(尤其是自 python 3.3 以来的 yield from)使协程的实现变得更加容易,并且 pythonic.

使用生成器,您可以轻松地将代码分为初始部分和回调。

@asyncio.coroutine
def print_sum(x, y):
    result = yield from compute(x, y)

    #write callback code
    print("%s + %s = %s" % (x, y, result))

没有功能区别。 "Native coroutines" 使用 asyncawait 关键字只是以前在 "generator-based coroutines."

中实现的语法糖

3.5 docs推荐使用asyncawait 如果不需要支持旧的Python版本.

扩展 Mike S 所写的内容:CPython 中的本机协程与生成器共享大部分相同的代码,因此几乎没有功能差异。但是,我认为 PEP-492 超过了 "syntactic sugar" 的阈值。生成器和本机协程具有不同的目的,因此新语法阐明了作者的意图并且可以完成旧语法无法完成的事情。以下是一些示例:

  • 生成器是可迭代的,而原生协程不是。
  • 本机协程还允许使用新语法,例如异步上下文管理器和异步迭代器。
  • 协同程序具有有用的调试消息,例如如果您从未 await 协程对象,则会发出警告。

新语法也很好地反映了 asyncio 库并且类似于其他语言中使用的关键字。