Generators and exceptions (was Re: Stackless Python and Python 2.x)
Tim Peters
tim.one at home.com
Thu Sep 6 23:29:04 EDT 2001
[Aahz]
> Okay, I've re-read PEP 255, and I'm still not clear on what happens with
> the following code:
>
> def a():
> yield 1
> raise "foo"
> yield 2
> return
It's impossible to get to the "yield 2", of course.
> def b():
> return a()
When called, returns a generator (iterator) for the generator (function) a.
> g = b()
The point to the b function isn't clear to me. Everything works the same if
you get rid of b and replace the line above with
g = a()
> g.next()
a is resumed, it executes the "yield 1" and suspends, returning 1 as the
value of the "g.next()" expression. Note that the b function has nothing to
do with this: a generator always returns to its immediate *invoker*, not
necessarily to the function that created the iterator. After "g = b()", b's
role in this is finished.
> g.next()
a is resumed, it executes the 'raise "foo"', and (from PEP 255)
If an unhandled exception-- including, but not limited to,
StopIteration --is raised by, or passes through, a generator
function, then the exception is passed on to the caller in the
usual way,
Again, b is long gone, and is in no way "the caller" of g.next(). So the
result of this is:
Traceback (most recent call last):
File "aahz.py", line 14, in ?
g.next()
File "aahz.py", line 5, in a
raise "foo"
foo
Your code ends there, but the PEP doesn't <wink>:
and subsequent attempts to resume the generator function raise
StopIteration. In other words, an unhandled exception terminates
a generator's useful life.
So if we change your last two lines from
g.next()
g.next()
to
print g.next() # 1
try:
print g.next() # 2
except "foo": # dangerous -- exceptions are compared by identity,
# not value, and this works by accident
print "OK, foo was raised"
print g.next() # 3
then the output becomes
1
OK, foo was raised
Traceback (most recent call last):
File "aahz.py", line 19, in ?
print g.next() # 3
StopIteration
An unhandled exception kills all flavors of functions, generators included.
BTW, I suspect your view of generators is too complex, not too simple. So
try to unlearn something that isn't true <wink>.
More information about the Python-list
mailing list