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:

  1. native coroutine objects not implement __iter__ , __next__ methods. therefore, cannot iterated on or passed iter(), list(), tuple() , other built-ins. cannot used in for..in loop.

    an attempt use __iter__ or __next__ on native coroutine object result in typeerror .

  2. plain generators cannot yield from native coroutines: doing result in typeerror .

  3. generator-based coroutines (for asyncio code must decorated @asyncio.coroutine) can yield from native coroutine objects.

  4. inspect.isgenerator() , inspect.isgeneratorfunction() return false 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

Popular posts from this blog

php - How to display all orders for a single product showing the most recent first? Woocommerce -

asp.net - How to correctly use QUERY_STRING in ISAPI rewrite? -

angularjs - How restrict admin panel using in backend laravel and admin panel on angular? -