Python 的 asyncio.coroutine 可以被认为是一个生成器吗?

Can Python's asyncio.coroutine be thought of as a generator?

我用谷歌搜索 python coroutine,只看到生成器(几乎所有示例都使用 yield 而没有 asyncio。)

它们真的一样吗?

asyncio.coroutine 和生成器有什么区别?

Python 中的大多数协程实现(包括 asynciotornado 提供的协程实现)都是使用生成器实现的。自 PEP 342 - Coroutines via Enhanced Generators made it possible to send values into running generator objects, which enabled the implementation simple coroutines. Coroutines technically are generators, they're just designed to be used in a very different way. In fact, the PEP for asyncio explicitly states this:

以来就是这种情况

A coroutine is a generator that follows certain conventions.

asyncio.coroutine 一个生成器。毫不夸张地说:

>>> import asyncio
>>> @asyncio.coroutine
... def mycoro():
...   yield from asyncio.sleep(1)
... 
>>> a = mycoro()
>>> a
<generator object mycoro at 0x7f494b5becf0>

同样,区别在于这两种东西的使用方式。尝试像普通生成器一样迭代 asyncio.coroutine 是行不通的:

>>> next(a)
Future<PENDING>
>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in mycoro
  File "/usr/lib/python3.4/asyncio/tasks.py", line 548, in sleep
    return (yield from future)
  File "/usr/lib/python3.4/asyncio/futures.py", line 349, in __iter__
    assert self.done(), "yield from wasn't used with future"
AssertionError: yield from wasn't used with future

很明显,您并不打算遍历它。你只是想 yield from 它,或者使用 asyncio.create_taskasyncio.async.

asyncio 事件循环中注册它

正如我之前提到的,从 PEP 342 开始就可以使用生成器实现协程,这比 asyncioyield from 出现要早得多;该功能是在 2005 年添加的。asyncioyield from 只是添加了使编写协程更容易的功能。