Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3 exception deletes variable in enclosing scope for unknown reason [duplicate]

I have the following code:

def foo():
    e = None
    try:
        raise Exception('I wish you would except me for who I am.')
    except Exception as e:
        print(e)
    print(e)

foo()

In Python 2.7, this runs as expected and prints:

I wish you would except me for who I am.
I wish you would except me for who I am.

However in Python 3.x, the first line is printed, but the second line is not. It seems to delete the variable in the enclosing scope, giving me the following traceback from the last print statement:

Traceback (most recent call last):
  File "python", line 9, in <module>
  File "python", line 7, in foo
UnboundLocalError: local variable 'e' referenced before assignment

It is almost as if a del e statement is inserted after the except block. Is there any reasoning for this sort of behavior? I could understand it if the Python developers wanted except blocks to have their own local scope, and not leak into the surrounding scope, but why must it delete a variable in the outer scope that was previously assigned?

like image 920
Shashank Avatar asked Mar 26 '15 00:03

Shashank


People also ask

What is enclosed scope in Python?

Enclosing (or nonlocal) scope is a special scope that only exists for nested functions. If the local scope is an inner or nested function, then the enclosing scope is the scope of the outer or enclosing function. This scope contains the names that you define in the enclosing function.

What is scope in Python explain with an example?

The scope defines the accessibility of the python object. To access the particular variable in the code, the scope must be defined as it cannot be accessed from anywhere in the program. The particular coding region where variables are visible is known as scope.

What is the scope of a variable in Python?

A variable is only available from inside the region it is created. This is called scope.

What is local scope and global scope in Python?

Variables that are defined inside a function body have a local scope, and those defined outside have a global scope. This means that local variables can be accessed only inside the function in which they are declared, whereas global variables can be accessed throughout the program body by all functions.


1 Answers

Quoting the documentation of try,

When an exception has been assigned using as target, it is cleared at the end of the except clause. This is as if

except E as N:
   foo

was translated to

except E as N:
    try:
        foo
    finally:
        del N

This means the exception must be assigned to a different name to be able to refer to it after the except clause. Exceptions are cleared because with the traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs.

This is covered in these two PEPs.

  1. PEP 3110 - Catching Exceptions in Python 3000

  2. PEP 344 - Exception Chaining and Embedded Tracebacks

like image 176
thefourtheye Avatar answered Oct 09 '22 10:10

thefourtheye