Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scope of caught exception instance in Python 2 and 3

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?

like image 282
Chris_Rands Avatar asked May 30 '17 09:05

Chris_Rands


People also ask

How do I see exception messages in Python?

If you want the error class, error message, and stack trace, use sys. exc_info() . The function sys. exc_info() gives you details about the most recent exception.

What is except exception as e?

except: accepts all exceptions, whereas. except Exception as e: only accepts exceptions that you're meant to catch. Here's an example of one that you're not meant to catch: >>> try: ...

Can I use try without except in Python?

Use the pass statement to use a try block without except. The pass statement does nothing and is used when a statement is required syntactically but the program requires no action.


1 Answers

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.

like image 179
Chris_Rands Avatar answered Oct 10 '22 02:10

Chris_Rands