Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The yield statement is a control flow mechanism used within a function body to transform that function into a generator. When evaluated, yield temporarily suspends the function’s execution, preserves its local execution state (including variable bindings, the instruction pointer, and the internal stack), and produces a value to the caller. Unlike a return statement, which terminates a function and destroys its local frame, yield allows the function to be resumed exactly where it left off upon subsequent invocations.
def generator_function():
    value = 42
    # Execution pauses here and yields the evaluated expression
    yield value 

Execution Mechanics

The presence of a yield statement fundamentally alters how a Python function operates at the bytecode level.
  1. Initialization: During the initial parsing and compilation phase, Python identifies the yield statement and compiles the function into bytecode, setting the CO_GENERATOR flag. At runtime, invoking the function does not execute its body; instead, it simply instantiates and returns a generator iterator object.
  2. Execution Trigger: The function’s body only begins executing when the built-in next() function is called on the generator object (which internally invokes the __next__() dunder method).
  3. Suspension: Execution proceeds until it encounters a yield statement. The expression to the right of the yield is evaluated and passed back to the caller. This expression is optional; if omitted (i.e., a bare yield), it defaults to yielding None. The function’s state is then frozen.
  4. Resumption: Upon the next call to next(), execution resumes immediately after the last executed yield statement, with all local variables retaining their previous values.
  5. Termination: If the function body finishes executing or encounters a return statement, it raises a StopIteration exception, signaling to the caller that the generator is exhausted.
def stateful_execution():
    x = 10
    yield x        # State frozen; yields 10
    
    x += 5
    yield x        # State frozen; yields 15
    
    yield          # Bare yield; yields None

gen = stateful_execution()
next(gen)          # Returns 10
next(gen)          # Returns 15
next(gen)          # Returns None

# next(gen)        # Raises StopIteration

yield as an Expression

In Python, yield is an expression, meaning it evaluates to a value. This allows the caller to inject data back into the suspended generator using the .send(value) method. When .send(value) is called, the generator resumes, and the yield expression evaluates to the passed value. If the generator is resumed via next(), the yield expression evaluates to None.
def bidirectional_generator():
    # The generator yields "Ready", then pauses.
    # Upon resumption via .send(), 'received' is bound to the sent value.
    received = yield "Ready"
    yield received

gen = bidirectional_generator()
next(gen)               # Primes the generator, returns "Ready"
gen.send("Injected")    # Resumes execution, 'received' becomes "Injected", returns "Injected"
Note: A generator must be “primed” by calling next() (or .send(None)) before it can receive a value via .send(), as execution must be paused at a yield statement to receive data.

Delegation with yield from

The yield from syntax establishes a transparent, bidirectional connection between the caller and a subgenerator. It delegates the yielding of values to another iterable or generator, automatically handling the StopIteration exception and propagating .send(), .throw(), and .close() calls down to the subgenerator.
def sub_generator():
    yield 1
    yield 2

def delegating_generator():
    # Exhausts sub_generator, yielding its values directly to the caller
    yield from sub_generator() 
    yield 3

gen = delegating_generator()
list(gen) # Evaluates to [1, 2, 3]
Master Python with Deep Grasping Methodology!Learn More