item4
item4

Reputation: 785

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

I googled python coroutine, and saw only generators (Almost almost all the examples use yield without asyncio.)

Are they really the same?

What is the difference between asyncio.coroutine and a generator?

Upvotes: 6

Views: 990

Answers (1)

dano
dano

Reputation: 94881

Most coroutine implementations in Python (including those provided by asyncio and tornado) are implemented using generators. This has been the case since 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 is a generator. Quite literally:

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

The difference, again, is in how the two things are meant to be used. Trying to iterate over a asyncio.coroutine like an ordinary generator will not work:

>>> 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

Clearly, you're not meant to iterate over it. You're only meant to yield from it, or register it with the asyncio event loop using asyncio.create_task or asyncio.async.

As I mentioned earlier, it's been possible to implement coroutines using generators since PEP 342, which was long before asyncio or yield from came along; that feature was added back in 2005. asyncio and yield from just add features that make writing coroutines easier.

Upvotes: 3

Related Questions