我用Google搜索python coroutine
,只看到了生成器(几乎所有示例都使用yield
而没有asyncio
。)
它们真的一样吗?
asyncio.coroutine
和生成器有什么区别?
答案 0 :(得分:3)
Python中的大多数协程实现(包括asyncio
和tornado
提供的实现)都是使用生成器实现的。这是因为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
,或使用asyncio
或asyncio.create_task
在asyncio.async
事件循环中注册。
正如我之前提到的,自从PEP 342开始使用生成器之后就可以实现协同程序,这是在asyncio
或yield from
出现之前很久的事情;该功能已于2005年添加。asyncio
和yield from
只是添加了使协同写入更容易的功能。