There seem to be two kinds of generator-based coroutine:
From a reply by Jim Fasarakis Hilliard:
Generator-based coroutine: A generator (
def
+yield
) that is wrapped bytypes.coroutine
. You need to wrap it intypes.coroutine
if you need it to be considered a coroutine object.From Python in a Nutshell, which doesn't explicitly call it "generator-based coroutine":
When you write Python code based on
asyncio
(ideally also using add-on modules from asyncio.org), you’ll usually be writing coroutine functions. Up to Python 3.4 included, such functions are generators using theyield from
statement covered in “yield from (v3-only)” on page 95, decorated with@asyncio.coroutine
, covered in “asyncio coroutines” on page 518;From https://www.python.org/dev/peps/pep-0492/#differences-from-generators
generator-based coroutines (for asyncio code must be decorated with @asyncio.coroutine)
http://masnun.com/2015/11/13/python-generators-coroutines-native-coroutines-and-async-await.html also calls it "generator-based coroutine".
Are the two kinds of generator-based coroutines the same concept?
If not, what are their differences in purposes and usages?
Thanks.
As far as I’m concerned,
async def
is the proper way to define a coroutine.yield
andyield from
have their purpose in generators, and they are also used to implement “futures”, which are the low-level mechanism that handles switching between different coroutine contexts.I did this diagram a few months ago to summarize the relationships between them. But frankly, you can safely ignore the whole business. Event loops have the job of handling all the low-level details of managing the execution of coroutines, so use one of those, like asyncio. There are also
asyncio
-compatible wrappers for other event loops, like my ownglibcoro
for GLib/GTK.In other words, stick to the
asyncio
API, and you can write “event-loop-agnostic” coroutines!They're the same kind of coroutine.
types.coroutine
andasyncio.coroutine
are just two separate ways to create them.asyncio.coroutine
is older, predating the introduction ofasync
coroutines, and its functionality has shifted somewhat from its original behavior now thatasync
coroutines exist.asyncio.coroutine
andtypes.coroutine
have subtly different behavior, especially if applied to anything other than a generator function, or if asyncio is in debug mode.