Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between @types.coroutine and @asyncio.coroutine decorators?

Tags:

Documentations say:

@asyncio.coroutine

Decorator to mark generator-based coroutines. This enables the generator use yield from to call async def coroutines, and also enables the generator to be called by async def coroutines, for instance using an await expression.

_

@types.coroutine(gen_func)

This function transforms a generator function into a coroutine function which returns a generator-based coroutine. The generator-based coroutine is still a generator iterator, but is also considered to be a coroutine object and is awaitable. However, it may not necessarily implement the __await__() method.

So is seems like purposes is the same - to flag a generator as a coroutine (what async defin Python3.5 and higher does with some features).

When need to use asyncio.coroutine when need to use types.coroutine, what is the diffrence?

like image 719
comalex3 Avatar asked Sep 22 '16 11:09

comalex3


People also ask

What is Asyncio coroutine?

async def is a new syntax from Python 3.5. You could use await , async with and async for inside async def s. @coroutine is a functional analogue for async def but it works in Python 3.4+ and utilizes yield from construction instead of await . For practical perspective just never use @coroutine if your Python is 3.5+.

Is coroutine deprecated?

Deprecated since version 3.8: If any awaitable in aws is a coroutine, it is automatically scheduled as a Task. Passing coroutines objects to wait() directly is deprecated as it leads to confusing behavior.

What is a coroutine in Python?

Coroutines are generalizations of subroutines. They are used for cooperative multitasking where a process voluntarily yield (give away) control periodically or when idle in order to enable multiple applications to be run simultaneously.

What is native coroutine?

Native coroutines in Python. We have seen that coroutines can be implemented in Python based on generators. A coroutine, then, is a generator function which runs until it is suspended using yield. At a later point in time, it can be resumed using send.


1 Answers

The difference is if you have a yield statement or not. Here's the code:

from types import coroutine as t_coroutine from asyncio import coroutine as a_coroutine, ensure_future, sleep, get_event_loop   @a_coroutine def a_sleep():     print("doing something in async")     yield 1   @t_coroutine def t_sleep():     print("doing something in types")     yield 1   async def start():     sleep_a = a_sleep()     sleep_t = t_sleep()     print("Going down!")   loop = get_event_loop() loop.run_until_complete(start()) 

In this example everything seem same - here's the debugging info from pycharm (we're standing on the "Going down!" line). Nothing is printed in console yet, so the functions didn't start yet.

PyCharm Debug

But if we remove the yield, the types version will start function instantly!

from types import coroutine as t_coroutine from asyncio import coroutine as a_coroutine, ensure_future, sleep, get_event_loop   @a_coroutine def a_sleep():     print("doing something in async")   @t_coroutine def t_sleep():     print("doing something in types")   async def start():     sleep_a = a_sleep()     sleep_t = t_sleep()     print("Going down!")   loop = get_event_loop() loop.run_until_complete(start()) 

Now we have doing something in types in console printed. And here's the debug info:

new debug info

As you can see it starts right after call, if there is no result and returns None.


As for usage, you should use asyncio version always. If you need to run it like fire and forget (running instantly and getting results later) - use ensure_future function.

like image 69
Dmitry Arkhipenko Avatar answered Oct 15 '22 11:10

Dmitry Arkhipenko