python - @asyncio.coroutine vs async def -
with asyncio
library i've seen,
@asyncio.coroutine def function(): ...
and
async def function(): ...
used interchangeably.
is there functional difference between two?
yes, there functional differences between native coroutines using async def
syntax , generator-based coroutines using asyncio.coroutine
decorator.
according pep 492, introduces async def
syntax:
native coroutine objects not implement
__iter__
,__next__
methods. therefore, cannot iterated on or passediter()
,list()
,tuple()
, other built-ins. cannot used infor..in
loop.an attempt use
__iter__
or__next__
on native coroutine object result in typeerror .plain generators cannot
yield from
native coroutines: doing result in typeerror .generator-based coroutines (for asyncio code must decorated
@asyncio.coroutine
) canyield from
native coroutine objects.
inspect.isgenerator()
,inspect.isgeneratorfunction()
returnfalse
native coroutine objects , native coroutine functions.
point 1 above means while coroutine functions defined using @asyncio.coroutine
decorator syntax can behave traditional generator functions, defined async def
syntax cannot.
here 2 minimal, ostensibly equivalent coroutine functions defined 2 syntaxes:
import asyncio @asyncio.coroutine def decorated(x): yield x async def native(x): await x
although bytecode these 2 functions 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
... difference being get_yield_from_iter
vs get_awaitable
, behave differently when attempt made iterate on objects return:
>>> list(decorated('foo')) ['f', 'o', 'o']
>>> list(native('foo')) traceback (most recent call last): file "<stdin>", line 1, in <module> typeerror: 'coroutine' object not iterable
obviously 'foo'
not awaitable, attempt call native()
doesn't make sense, point clear coroutine
object returns not iterable, regardless of argument.
a more detailed investigation of async
/await
syntax brett cannon: how heck async/await work in python 3.5? covers difference in more depth.
Comments
Post a Comment