Python: Yes, coroutines are complicated, but they can be used as simply as generators
The fact is that we often take the .send()
sematics of coroutines too seriosly that we simply ignore the possibility to use them just like generators.
def simple_generator():
yield
yield
yield
def simple_coroutine():
x = yield
y = yield
z = yield
print("[simple_coroutine] after 3 yields, x = {}, y = {}, z = {}".format(x, y, z))
# return value of coroutines are not used in our examples
# so having a return-statement or not does not matter here
# return (x, y, z)
def simple_generator2():
yield 1
yield 2
yield 3
def simple_coroutine2():
x = yield 1
y = yield 2
z = yield 3
print("[simple_coroutine2] after 3 yields, x = {}, y = {}, z = {}".format(x, y, z))
# return (x, y, z)
# Or simply `my_gen = (None for _ in range(3))`
# Prefer generator functions here for better comparison of code
my_gen = simple_generator()
my_coro = simple_coroutine()
my_gen2 = simple_generator2()
my_coro2 = simple_coroutine2()
def yield_from(sth):
yield from sth
print(list(yield_from(my_gen)))
print("------------------")
print(list(yield_from(my_coro)))
print("------------------")
print(list(yield_from(my_gen2)))
print("------------------")
print(list(yield_from(my_coro2)))
# Output:
"""
[None, None, None]
------------------
[simple_coroutine] after 3 yields, x = None, y = None, z = None
[None, None, None]
------------------
[1, 2, 3]
------------------
[simple_coroutine2] after 3 yields, x = None, y = None, z = None
[1, 2, 3]
"""
- A simple
yield
with no argument, yieldsNone
- A statement like
x = yield
, with no argument afteryield
, yieldsNone
(same in a generator’s way) - Priming a coroutine does trigger the first
yield
, which will yield something (same in a generator’s way)- Recall that
next(coro)
andcoro.send(None)
both serve as primers.- The consistency of
next(coro)
andcoro.send(None)
in the ability to prime a coroutine is actually a good clue to follow!
- The consistency of
- Recall that
Comments