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

ite*_*em4 6 python coroutine python-3.x python-asyncio

我用谷歌搜索python coroutine,只看到了发电机(几乎所有的例子yield都没用asyncio.)

它们真的一样吗?

asyncio.coroutine和发电机有什么区别?

dan*_*ano 3

asyncioPython 中的大多数协程实现(包括和提供的协程tornado实现)都是使用生成器实现的。自PEP 342 - 通过增强型生成器的协程可以将值发送到正在运行的生成器对象中以来,情况一直如此,这使得实现简单的协程成为可能。从技术上讲,协程生成器,它们只是被设计为以非常不同的方式使用。事实上,PEPasyncio 明确指出了这一点

协程是遵循某些约定的生成器。

asyncio.coroutine 一个发电机。毫不夸张的说:

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

同样,区别在于这两个东西的使用方式。尝试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
Run Code Online (Sandbox Code Playgroud)

显然,你不应该迭代它。您只是有意为之yield from,或者asyncio使用asyncio.create_task或将其注册到事件循环中asyncio.async

正如我之前提到的,自 PEP 342 以来就可以使用生成器来实现协程,而 PEP 342 早在很久以前asyncioyield from已经出现了;该功能是在 2005 年添加的。asyncio并且yield from只是添加了使编写协程更容易的功能。