@asyncio.coroutine vs async def
@asyncio.coroutine vs async def
Is there any practical difference between using the @asyncio.coroutine decorator and async keyword before def function?
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: @asyncio.coroutine vs async def
No. However async def is the more modern syntax and is preferable in my opinion. I think it's best to adopt a consistent syntax.
CPython's asyncio went through various iterations leading to much confusion. There is a tutorial in this repo which promotes using the newest syntax for consistency. Programs written using those guidelines will be portable to CPython/asyncio except in the few clearly stated instances.
CPython's asyncio went through various iterations leading to much confusion. There is a tutorial in this repo which promotes using the newest syntax for consistency. Programs written using those guidelines will be portable to CPython/asyncio except in the few clearly stated instances.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: @asyncio.coroutine vs async def
Thank you Peter, for your quick reply.
Of course i've already found your helpful tutorial.
Nevertheless there are many questions. But that's not your fault. I'm quite new to python and this asyncio stuff in particular.
Hm, i've found this in uasyncio core:
As far as i understand this decorator does exactly nothing?
By the way: where does the "async" keyword come from? Is this a language extension?
Of course i've already found your helpful tutorial.
Nevertheless there are many questions. But that's not your fault. I'm quite new to python and this asyncio stuff in particular.
Hm, i've found this in uasyncio core:
Code: Select all
def coroutine(f):
return f
By the way: where does the "async" keyword come from? Is this a language extension?
Re: @asyncio.coroutine vs async def
There's a lot to unpack here... I'm not 100% I have this right but I think the overall answer is that the MicroPython implementation of async is quite closely aligned with the generator style of coroutines, whereas CPython has slightly different handling for "new style" async methods. So if you're writing an old-style co-routine (i.e. using yield), then the method will already be a generator (because it will contain yield statements) and will look exactly like an async method anyway. This is kind of an optimisation in MicroPython (which does lead to some small but mostly not noticeable differences to CPython). So this "do nothing" decorator just exists for compatibility with existing Python code that needs it to be there (because CPython does treat them differently internally).
To put it another way, in MicroPython, any generator (i.e. a method containing yields) already behaves like an async function, so the decorator does nothing.
You don't need to know this sort of stuff to use asyncio effectively. As Pete says, stick to the modern async/await syntax.
It's a standard feature in Python since 3.5. See https://www.python.org/dev/peps/pep-049 ... ion-syntax which is the full story behind its addition to the language.
Re: @asyncio.coroutine vs async def
Thank you jimmo,
that makes something clear.
that makes something clear.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: @asyncio.coroutine vs async def
@klauweg As @jimmo says MicroPython makes no distinction between tasks (coroutines) and generators. In CPython they are entirely separate and any attempt to substitute one for the other will produce a syntax error. In the interests of code clarity (and CPython compatibility) I recommend treating the two as if they were different. This implies using async def and avoiding the use of yield in a task:
In performance-critical code yield does offer a small advantage. There are other tricks such as yielding an integer (number of milliseconds to pause). In the great majority of cases code clarity trumps the small performance gain achieved by these hacks. In my opinion, of course.
Code: Select all
import uasyncio as asyncio
async def foo():
while True:
# Do something
await asyncio.sleep_ms(0) # Not yield
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.