Since Python 3.3, if a generator function returns a value, that becomes the value for the StopIteration exception that is raised. This can be collected a number of ways:
- The value of a
yield from
expression, which implies the enclosing function is also a generator. - Wrapping a call to
next()
or.send()
in a try/except block.
However, if I'm simply wanting to iterate over the generator in a for loop - the easiest way - there doesn't appear to be a way to collect the value of the StopIteration exception, and thus the return value. Im using a simple example where the generator yields values, and returns some kind of summary at the end (running totals, averages, timing statistics, etc).
for i in produce_values():
do_something(i)
values_summary = ....??
One way is to handle the loop myself:
values_iter = produce_values()
try:
while True:
i = next(values_iter)
do_something(i)
except StopIteration as e:
values_summary = e.value
But this throws away the simplicity of the for loop. I can't use yield from
since that requires the calling code to be, itself, a generator. Is there a simpler way than the roll-ones-own for loop shown above?
e.value
, not juste
.) – Personalsummary
method, to be called once iteration completes. – Personal__next__
a generator function just makes your iterator return an endless stream of generators.) – Personal