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 .
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')
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)
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 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'>
Copied from snippets
def Y():
print ('yiedling foo')
yield 'foo'
print ('yielding bar')
yield 'bar'
print ('yielding baz')
yield 'baz'
for y in Y():
print ('y: ' + y)
# yiedling foo
# y: foo
# yielding bar
# y: bar
# yielding baz
# y: baz
def YY():
for i in ['FOO', 'BAR', 'BAZ']:
print ('yielding ' + i)
yield i
for yy in YY():
print ('yy: ' + yy)
# yielding FOO
# yy: FOO
# yielding BAR
# yy: BAR
# yielding BAZ
# yy: BAZ
def YYY():
for i in [1, 2, 3, 4, 5, 6]:
if i != 3:
print ('yielding ' + str(i))
yield i
else:
return
# Note:
# numbers 3 through 6 are not printed.
for yyy in YYY():
print 'yyy: ' + str(yyy)
# yielding 1
# yyy: 1
# yielding 2
# yyy: 2
See also
342 edefined
ield to be an expression rather than a statement.