Step 6 - The Intermediate Function Issue¶
Our current concept uses generator functions to call generator functions. But what about normal functions calling generators in between?
def loop(coroutine):
"""Loop v1"""
step = 1
while True:
print("Loop step", step)
try:
next(coroutine)
step += 1
except StopIteration as e:
return e.value
from loop import loop
def generator_one():
print(generator_one.__name__, 1)
yield
print(generator_one.__name__, 2)
def generator_two():
print(generator_two.__name__, 1)
yield
print(generator_two.__name__, 2)
yield
print(generator_two.__name__, 3)
def intermediate_function():
print(intermediate_function.__name__, 1)
generator_two()
print(intermediate_function.__name__, 2)
def chaining_generator():
print(chaining_generator.__name__, 1)
yield from generator_one()
print(chaining_generator.__name__, 2)
intermediate_function()
print(chaining_generator.__name__, 3)
def main_generator():
print(main_generator.__name__, 1)
yield from chaining_generator()
print(main_generator.__name__, 2)
result = loop(main_generator())
print("Loop finished with result", result)
Output:
Loop step 1
main_generator 1
chaining_generator 1
generator_one 1
Loop step 2
generator_one 2
chaining_generator 2
intermediate_function 1
intermediate_function 2
chaining_generator 3
main_generator 2
Loop finished
As we can see the intermediate_function
has run but generator_two
is never
executed. The intermediate_function
is blocking our generator based code from
being executed as expected. The only way to fix this is to run another loop in
the intermediate_function
or to use the yield from
statement again. But
using yield from
would also convert the normal function into a generator
function.
Summary
Calling coroutines from normal functions breaks the concept.
Therefore normal functions must not call coroutines.
Coroutines are allowed to call normal functions.