Question

How can you explain this:

This code is supposed to override the NameError and then catch it.

OldNameError = NameError
class NameError(OldNameError):
    pass

try:
    ccc
except NameError as e:
    print "hi"

Does not print "hi". Instead, the output is:

Traceback (most recent call last):
  File "try.py", line 6, in <module>
    ccc
NameError: name 'ccc' is not defined

But this code:

OldNameError = NameError
class NameError(OldNameError):
    pass

try:
    raise NameError("oo")
except NameError:
    print "hi"

Gives the output I wanted:

hi

What is the explanation?

Thanks!

Was it helpful?

Solution

When you write except NameError, you are saying you want to catch exceptions of the type of whatever NameError refers to at the moment you do the catching. Since you changed what NameError is, you are trying to catch your new class. But the exception that is raised is a "real" NameError, not your overriden one.

You can see this if you modify your except clause:

try:
    ccc
except Exception as e:
    print isinstance(e, NameError)
    print isinstance(e, OldNameError)

The output is:

False
True

. . . indicating that the raised exception is an OldNameError, not your new NameError.

You cannot change what kind of exception is raised due to an undefined name. You can create something called NameError, but it will never be used unless you use it explicitly yourself (as you did in your second example).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top