Step 3 - Adding yield from
¶
In the last steps we needed to catch the StopIteration
of each coroutine to
get their values. And even further we needed to catch it at the right resume
call with next. What if we could resume the coroutines until we are just done
and get the values automatically?
That is where yield from
comes into play. We abstract our business logic into
a single main generator function and call the coroutines via yield from
.
Afterwards we can call the main generator function easily in a while loop until
StopIteration
is raised.
def generator():
# do something
yield # something
# do something else
yield # something else
# do another thing
return # some value
def other_generator():
# do something
yield # something
# do something else
return # other value
def main_generator():
some_value = yield from generator()
# yield from generator() is the same as
# gen = generator()
# try:
# while True:
# x = next(gen)
# yield x
# except StopIteration as e:
# some_value = e.value
other_value = yield from other_generator()
# yield from other_generator() is the same as
# gen = other_generator()
# try:
# while True:
# x = next(gen)
# yield x
# except StopIteration as e:
# some_value = e.value
return (some_value, other_value)
gen = main_generator()
while True:
try:
next(gen)
except StopIteration as e:
return e.value
Summary
Using
yield from
allows to write call flow sequences as they would just contain normal function calls.Using a single main generator allows for simplifying the business logic without having to care about the
Generator
boilerplate (next iteration, catchingStopIteration
).