Tuesday, December 28, 2010

using finally to do something after return

>>> def foo():
...    try:
...       print "returning"
...       return
...    finally:
...       print "after return"
...
>>> foo()
returning
after return

2 comments:

  1. well, that is not the correct output, infact it will hold what is in return and execute finally then release what has to be returned.

    ReplyDelete
  2. Yes, you are correct that the return is stored. It is just kind of a brain puzzler, "when does a return statement not halt execution of a function?"

    It is even possible to overwrite the returning value in a finally block:

    >>> def foo():
    ... try:
    ... return 1
    ... finally:
    ... return 2
    ...
    >>> foo()
    2


    We can look inside the compiled function with dis.dis() to see no funny business. The compiler isn't doing any transformations to this structure, the VM is seeing two RETURN_VALUE separate op codes.

    >>> dis.dis(foo)
    2 0 SETUP_FINALLY 8 (to 11)

    3 3 LOAD_CONST 1 (1)
    6 RETURN_VALUE
    7 POP_BLOCK
    8 LOAD_CONST 0 (None)

    5 >> 11 LOAD_CONST 2 (2)
    14 RETURN_VALUE
    15 END_FINALLY

    ReplyDelete