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 def
in Python3.5 and higher does with some features).
When need to use asyncio.coroutine
when need to use types.coroutine
, what is the diffrence?
One other subtle difference: generator-based coroutines decorated with
@asyncio.coroutine
will testTrue
forasyncio.iscoroutinefunction()
, while those decorated with@types.coroutine
will testFalse
.Output:
Nonetheless, both of these are awaitable.
*Note also that this difference does not apply to their _results: replace
iscoroutinefunction()
withiscoroutine()
(which tests for a coroutine object), andold_coro_with_asyncio()
+old_coro_with_types()
will evaluate False for both.The difference is if you have a yield statement or not. Here's the code:
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.
But if we remove the
yield
, thetypes
version will start function instantly!Now we have
doing something in types
in console printed. And here's the 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) - useensure_future
function.