guarding for StopIteration (WAS: Help with generators outside of loops.)
Steven Bethard
steven.bethard at gmail.com
Wed Dec 8 03:36:18 EST 2004
David Eppstein wrote:
> I've made it a policy in my own code to always surround explicit calls
> to next() with try ... except StopIteration ... guards.
>
> Otherwise if you don't guard the call and you get an unexpected
> exception from the next(), within a call chain that includes a for-loop
> over another generator, then that other for-loop will terminate without
> any error messages and the cause of its termination can be very
> difficult to track down.
Just to clarify here, the only time code raising a StopIteration will
cause a for-loop to exit silently is if the StopIteration is raised in
an __iter__ method, e.g.:
>>> def g():
... raise StopIteration
...
>>> class C(object):
... def __iter__(self):
... for i in range(3):
... yield i
... g()
...
>>> for i in C():
... print i
...
0
>>>
A StopIteration raised within the body of a for-loop will not cause it
to terminate silently; the StopIteration exception will be propagated
upward:
>>> def g():
... raise StopIteration
...
>>> def f(n):
... for i in range(n):
... print i
... g()
...
>>> f(3)
0
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<interactive input>", line 4, in f
File "<interactive input>", line 2, in g
StopIteration
>>>
Steve
More information about the Python-list
mailing list