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

时间:2015-04-20 15:47:48

标签: python python-3.x coroutine python-asyncio

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

它们真的一样吗?

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

1 个答案:

答案 0 :(得分:3)

Python中的大多数协程实现(包括asynciotornado提供的实现)都是使用生成器实现的。这是因为PEP 342 - Coroutines via Enhanced Generators使得可以将值发送到正在运行的生成器对象,这使得实现简单的协同程序成为可能。协同技术上生成器,它们只是设计用于以非常不同的方式使用。事实上,asyncio explicitly states this的PEP:

  

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

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,或使用asyncioasyncio.create_taskasyncio.async事件循环中注册。

正如我之前提到的,自从PEP 342开始使用生成器之后就可以实现协同程序,这是在asyncioyield from出现之前很久的事情;该功能已于2005年添加。asyncioyield from只是添加了使协同写入更容易的功能。