[Python-Dev] capturing RETURN_VALUE
Tim Peters
tim.peters at gmail.com
Mon Aug 9 01:09:41 CEST 2004
[Christian Tismer]
> just by chance, I discovered a probably very unknown
> feature of the block stack machinery of Python's frames:
>
> -- It is possible to abandon a return statement. --
[if the return tickles an enclosing finally block, and the finally block, e.g.,
does a different return, or breaks out of a loop, or raises an exception]
> My question: Is this an artifact, or can I rely on this
> feature to persist for a while (while while >= 1 year) ?
Yes, it's reliable. The Java spec is clearer about it, but Python
acts the same way.
If Python allowed continue statements in finally blocks, you'd also
find that a finally block could "abandon" a break statement (if the
break tickled an enclosing finally block in the same loop, and the
finally block did a continue).
> I have a code body which either computes and returns a value,
> or it raises an exception. Surrounding it, I have a while
> true loop, embracing a try..finally block. In case of an
> exception, it simply lets the exception pass.
It did in your specific example, but not necessarily. In your
specific example, the finally block didn't execute "break" if an
exception was raised, it only did "break" if the finally block was
entered because of a return. If it had done "break" in the exception
case too, it would have "abandoned" the exception too:
def return_capture(n, do_raise=False):
_have_value = False
retval = 666
while True:
try:
if do_raise:
raise ValueError, "was told to raise"
_have_value = True
retval = n*n
return
finally:
break
retval = ("here the captured return value", retval)
return retval
>>> return_capture(12)
('here the captured return value', 144)
>>> return_capture(12, True)
('here the captured return value', 666)
>>>
So there's really no difference between how returns and exceptions work here.
More information about the Python-Dev
mailing list