Search code examples
pythonpython-3.xgeneratorabstract-syntax-treeyield

What happens when you invoke a function that contains yield?


I read here the following example:

>>> def double_inputs():
...     while True:      # Line 1
...         x = yield    # Line 2
...         yield x * 2  # Line 3
...
>>> gen = double_inputs()
>>> next(gen)       # Run up to the first yield
>>> gen.send(10)    # goes into 'x' variable

If I understand the above correctly, it seems to imply that Python actually waits until next(gen) to "run up to" to Line 2 in the body of the function. Put another way, the interpreter would not start executing the body of the function until we call next.

  1. Is that actually correct?
  2. To my knowledge, Python does not do AOT compilation, and it doesn't "look ahead" much except for parsing the code and making sure it's valid Python. Is this correct?
  3. If the above are true, how would Python know when I invoke double_inputs() that it needs to wait until I call next(gen) before it even enters the loop while True?

Solution

  • Correct. Calling double_inputs never executes any of the code; it simply returns a generator object. The presence of the yield expression in the body, discovered when the def statement is parsed, changes the semantics of the def statement to create a generator object rather than a function object.