Since in Python variables are accessible outside of their loops and try
-except
blocks, I naively thought that this code snippet below would work fine because e
would be accessible:
try:
int('s')
except ValueError as e:
pass
print(e)
In Python 2 (2.7 tested), it does work as I expected and the output is:
invalid literal for int() with base 10: 's'
However, in Python 3 I was surprised that the output is:
NameError: name 'e' is not defined
Why is this?
I later found an answer as PEP 3110 explains that in Python 3 the caught name is removed at the end of the except
suite to enable more efficient garbage collection. There is also recommended syntax if you wish to avoid this occurring:
Situations where it is necessary to keep an exception instance around
past the end of the except suite can be easily translated like so
try:
...
except E as N:
...
...
becomes
try:
...
except E as N:
n = N
...
…
This way, when N is deleted at the end of the block, n will persist
and can be used as normal.