python3.x scope in finally

Viewed 58

Python==3.6.9

def test():
    a = 2
    try:
        1 / 0
    except Exception as exc:
        return a
    finally:
        a += 1
        print(a)

print(test())

output is:

3
2

It's obvious that finally executes before return, if a is a immutable type, id(a) is different between finally scope and try\except scope;

I want to know how did this happen? Thanks

2 Answers

The built-in try statement does not create its own scope. Modules, classes, and functions create scope.

A complete description of Python scopes and namespaces in the docs.

Although scopes are determined statically, they are used dynamically. At any time during execution, there are at least three nested scopes whose namespaces are directly accessible:

  • the innermost scope, which is searched first, contains the local names

One of the great things about the finally block is that it guarantees an operation is executed when we exit the scope of the try-catch block. We are forced to exit the scope when we return from the function. So, before we return we do the guaranteed task in the finally block first. If we didn't do this task, there can be bad consequences. For Eg :

Assume I create a connection in try block and I close it in finally block. If I return the connection in the catch block without closing it in the finally block, the function caller can start operating on a supposedly dead connection.

Hence, as you already know, if we didn't have return :

def test():
    try:
        1 / 0
    except Exception as exc:
        print("hi")
    finally:
        print("bye)

print(test())

The output will be

hi
bye
Related