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..inloop.an attempt use
__iter__or__next__on native coroutine object result in typeerror .plain generators cannot
yield fromnative coroutines: doing result in typeerror .generator-based coroutines (for asyncio code must decorated
@asyncio.coroutine) canyield fromnative coroutine objects.
inspect.isgenerator(),inspect.isgeneratorfunction()returnfalsenative 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