Search notes:

Python: yield statement

The yield statement is used to define a generator function.
When the Python interpreter encounters the yield statement, the function's local variables and execution state are saved and control is returned to the caller.
With next(), the execution is resumed from where the executions was suspended with the saved data.
Under the hood, next() calls an object's __next__() method.

Jumping between function and caller

The following example tries to demonstrate how it is possible to «jump» between a calling context and a function.
def func(init_val):

    local_var = init_val
    print(f'yielding {local_var}')
    yield local_var

    local_var += 5
    print(f'yielding {local_var}')
    yield local_var

    local_var *= 2
    print(f'yielding {local_var}')
    yield local_var

    print('the end.')

gen = func(17)

try:
    # gen.__iter__()
    print(f'__next()__ returned: {gen.__next__()}')
    print(f'__next()__ returned: {gen.__next__()}')
    print(f'__next()__ returned: {gen.__next__()}')
    print(f'__next()__ returned: {gen.__next__()}')
except StopIteration:
    print('Caught StopIteration')

print('--------------------------------------')

gen = func(5)
itr = iter(gen)

try:
    print(f'next(itr) = {next(itr)}')
    print(f'next(itr) = {next(itr)}')
    print(f'next(itr) = {next(itr)}')
    print(f'next(itr) = {next(itr)}')

except StopIteration:
    print('Caught StopIteration')
Github repository about-Python, path: /statements/yield/save-state-and-resume.py
When executed, the example prints
yielding 17
__next()__ returned: 17
yielding 22
__next()__ returned: 22
yielding 44
__next()__ returned: 44
the end.
Caught StopIteration
--------------------------------------
yielding 5
next(itr) = 5
yielding 10
next(itr) = 10
yielding 20
next(itr) = 20
the end.
Caught StopIteration

for … in …

A function with yield statements can be used in for … in … statements:
def Func():
    yield 'one'
    yield 'two'
    yield 'three'

for word in Func():
    print(word)
Github repository about-python, path: /statements/yield/for-in.py
This example prints:
one
two
three

Return type of a def with a yield statement

A function that is defined with def and that contains a yield statement returns a generator.
The following simple example defines two functions, one of which has a yield statement and the other doesn't.
The type of both functions is function. However, the type of returned object of the function without yield is int (the type of 42) while the the type of the returned object of the function with a yield is generator.
#!/usr/bin/python3


def FuncWithoutYield():
    return 42

def FuncWithYield():
    yield 42

print(type(FuncWithoutYield))
# <class 'function'>

print(type(FuncWithYield))
# <class 'function'>

retFuncWithoutYield = FuncWithoutYield()
retFuncWithYield    = FuncWithYield()

print(type(retFuncWithoutYield))
# <class 'int'>

print(type(retFuncWithYield))
# <class 'generator'>
Github repository about-python, path: /statements/yield/def-with-and-without-yield.py

See also

yield from
Using the yield statement in __reversed__().
statements

Index