On 1/30/2014 7:05 AM, Dave Angel wrote:
  Jessica Ross <deathwea...@gmail.com> Wrote in message:
I found something like this in a StackOverflow discussion.
def paradox():
...     try:
...             raise Exception("Exception raised during try")
...     except:
...             print "Except after try"
...             return True
...     finally:
...             print "Finally"
...             return False
...     return None
...
return_val = paradox()
Except after try
Finally
return_val
False

I understand most of this.
What I don't understand is why this returns False rather than True. Does the 
finally short-circuit the return in the except block?


The finally has to happen before any return inside the try or the
  except.  And once you're in the finally clause you'll finish it
  before resuming the except clause.  Since it has a return,  that
  will happen before the other returns. The one in the except block
  will never get reached.

It's the only reasonable behavior., to my mind.

Checking with the disassembled code, it appears that the except return happens first and is then caught and the value over-written

  2           0 SETUP_FINALLY           45 (to 48)
              3 SETUP_EXCEPT            16 (to 22)

  3           6 LOAD_GLOBAL              0 (Exception)
              9 LOAD_CONST               1 ('Exception raised during try')
             12 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             15 RAISE_VARARGS            1
             18 POP_BLOCK
             19 JUMP_FORWARD            22 (to 44)

  4     >>   22 POP_TOP
             23 POP_TOP
             24 POP_TOP

  5          25 LOAD_GLOBAL              1 (print)
             28 LOAD_CONST               2 ('Except after try')
             31 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             34 POP_TOP

  6          35 LOAD_CONST               3 (True)
             38 RETURN_VALUE
             39 POP_EXCEPT
             40 JUMP_FORWARD             1 (to 44)
             43 END_FINALLY
        >>   44 POP_BLOCK
             45 LOAD_CONST               0 (None)

  8     >>   48 LOAD_GLOBAL              1 (print)
             51 LOAD_CONST               4 ('Finally')
             54 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             57 POP_TOP

  9          58 LOAD_CONST               5 (False)
             61 RETURN_VALUE
             62 END_FINALLY

 10          63 LOAD_CONST               0 (None)
             66 RETURN_VALUE




--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to