async def function():
Yes, there are functional differences between native coroutines using
async def sytnax and generator-based coroutines using the
According to PEP 492, which introduces the
async def syntax:
Native coroutine objects do not implement
__next__methods. Therefore, they cannot be iterated over or passed to
tuple()and other built-ins. They also cannot be used in a
An attempt to use
__next__on a native coroutine object will result in a TypeError .
Plain generators cannot
yield fromnative coroutines: doing so will result in a TypeError .
generator-based coroutines (for asyncio code must be decorated with
yield fromnative coroutine objects.
Falsefor native coroutine objects and native coroutine functions.
Point 1 above means that while coroutine functions defined using the
@asyncio.coroutine decorator syntax can behave as traditional generator functions, those defined with the
async def syntax cannot.
Here are two minimal, ostensibly equivalent coroutine functions defined with the two syntaxes:
import asyncio @asyncio.coroutine def decorated(x): yield from x async def native(x): await x
Although the bytecode for these two functions is almost identical:
>>> import dis >>> dis.dis(decorated) 5 0 LOAD_FAST 0 (x) 3 GET_YIELD_FROM_ITER 4 LOAD_CONST 0 (None) 7 YIELD_FROM 8 POP_TOP 9 LOAD_CONST 0 (None) 12 RETURN_VALUE >>> dis.dis(native) 8 0 LOAD_FAST 0 (x) 3 GET_AWAITABLE 4 LOAD_CONST 0 (None) 7 YIELD_FROM 8 POP_TOP 9 LOAD_CONST 0 (None) 12 RETURN_VALUE
... the only difference being
GET_AWAITABLE, they behave completely differently when an attempt is made to iterate over the objects they return:
>>> list(decorated('foo')) ['f', 'o', 'o']
>>> list(native('foo')) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'coroutine' object is not iterable
'foo' is not an awaitable, so the attempt to call
native() with it doesn't make much sense, but the point is hopefully clear that the
coroutine object it returns is not iterable, regardless of its argument.
A more detailed investigation of the
await syntax by Brett Cannon: How the heck does async/await work in Python 3.5? covers this difference in more depth.