Search code examples
pythongeneratoryield

Unexecuted yield statement blocks function to run?


In the below simplified code, I would like to reuse a loop to do a preparation first and yield the result.

However, the preparation (bar()) function is never executed.

Is yield statement changing the flow of the function?

def bar(*args,**kwargs):
    print("ENTER bar")
    pass

def foo(prepare=False):
    print("ENTER foo")
    for x in range(1,10):
        if prepare:
            bar(x)
        else:
            yield x


foo(prepare=True)

r = foo(prepare=False)
for x in r:
    pass

Solution

  • Because the foo definition contains a yield, it won't run like a normal function even if you call it like one (e.g. foo(prepare=True) ).

    Running foo() with whatever arguments will return a generator object, suitable to be iterated through. The body of the definition won't be run until you try and iterate that generator object.

    The new coroutine syntax puts a keyword at the start of the definition, so that the change in nature isn't hidden inside the body of the function.