【问题标题】:Python can't catch overridden NameErrorPython 无法捕获被覆盖的 NameError
【发布时间】:2014-02-15 20:57:13
【问题描述】:

你怎么解释这个:

这段代码应该覆盖 NameError 然后捕获它。

OldNameError = NameError
class NameError(OldNameError):
    pass

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

不打印“hi”。 相反,输出是:

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

但是这段代码:

OldNameError = NameError
class NameError(OldNameError):
    pass

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

给出我想要的输出:

hi

解释是什么?

谢谢!

【问题讨论】:

    标签: python exception overriding nameerror


    【解决方案1】:

    当您编写except NameError 时,您是在说您想要捕获任何NameError 在您进行捕获时所指的类型的异常。由于您更改了 NameError 是什么,因此您正试图赶上您的新课程。但是引发的异常是“真实的”NameError,而不是您覆盖的异常。

    如果你修改你的 except 子句,你可以看到这个:

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

    输出是:

    False
    True
    

    。 . .表明引发的异常是 OldNameError,而不是您的新 NameError。

    您无法更改由于未定义名称而引发的异常类型。您可以创建一个称为 NameError 的东西,但除非您自己明确使用它(就像您在第二个示例中所做的那样),否则它永远不会被使用。

    【讨论】:

    • 为什么我不能更改提出的内容?它必须在某个地方定义,我应该能够覆盖它,不是吗?
    • @EllaShar:它没有在 Python 代码中定义。要更改它,您需要修改 Python 迭代器本身。你为什么要这样做?
    • 谢谢。但是当我写ccc 并且它没有被定义时会发生什么? python 如何“知道”要引发哪个异常?
    • @EllaShar:正如我所说,Python 解释器内置了这种行为。
    • @EllaShar:如果有帮助,您可以想象在解释器开始运行您的任何代码之前,某处有一些代码引用了NameError 类。然后使用对类的引用而不是使用其名称引发异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2011-12-13
    • 1970-01-01
    相关资源
    最近更新 更多