I stumbled on an interesting scenario following this question. Consider the following simple example:
try:
1/0
error = "error"
except Exception as error:
print(error)
print(error)
The output is:
division by zero
Traceback (most recent call last):
File "main.py", line 7, in <module>
print(error)
NameError: name 'error' is not defined
What happens is of course the first assignment to error
is skipped because of the exception, and the except
is executed. It prints the exception and - to my understanding - assigns, in a way, the exception object to error
. But then, surprisingly, the following print
complains that error
is not defined.
I tried to understand the scoping rule for exceptions but all I could find in the Exceptions docs was this:
The variable is bound to an exception instance
Which doesn't really explain what is the scope or life-span of this exception instance.
The most similar construct I can think of is a with
statement, which doesn't behave the same way:
with open("test.txt") as file:
pass
file.read()
This code will output a maybe expected output of:
Traceback (most recent call last):
File "main.py", line 4, in <module>
file.read()
ValueError: I/O operation on closed file.
But still it is not a NameError
which means that file
is well-defined.
So can anyone explain what are the scoping rules for exception handling and what is happening here?