【问题标题】:Why doesn't Python's `except` use `isinstance`?为什么 Python 的 `except` 不使用 `isinstance`?
【发布时间】:2010-10-01 22:35:16
【问题描述】:

Python documentationexcept 表示:

对于带有 表达式,那个表达式是 评估,并且该子句匹配 如果结果对象是异常 “兼容”例外。一个 对象与异常兼容 如果它是异常对象的类或基类,[...]

为什么except 不使用isinstance 而不是比较基类?这可以防止使用__instancecheck__ 覆盖实例检查。

编辑:

我可以理解,它不存在的原因之一是没有人考虑过它。但是有什么理由不应该实施吗?

编辑:

来自 Python 3.2a 的 Shell 会话显示尝试使用 __subclasscheck__ 不起作用:

>>> class MyType(type): __subclasscheck__ = lambda cls, other_cls: True
>>> class O(Exception, metaclass=MyType): pass
>>> issubclass(3, O)
0: True
>>> issubclass(int, O)
1: True
>>> try:
...     1/0
... except O:
...     print('Success')
Traceback (most recent call last):
  File "<pyshell#4>", line 2, in <module>
    1/0
ZeroDivisionError: division by zero
>>> 

【问题讨论】:

    标签: python exception exception-handling types isinstance


    【解决方案1】:

    简单的答案可能是没有人考虑过。一个更复杂的答案是没有人考虑它,因为很难做到这一点,因为这意味着在处理异常时执行潜在的任意 Python 代码,而且它的价值值得怀疑。 Python 中的异常类通常是非常简单的类,用功能重载它们通常是错误的。很难想象有什么案例可以咨询__instancecheck__。如果您有这种情况(有或没有补丁),请提交一个错误,有人可能会接手。

    【讨论】:

    • 我可以理解没有人考虑过的事实。我想我要问的是是否有充分的理由不这样做。 “这意味着在处理异常时执行潜在的任意 Python 代码”。我想我可以给出“同意的成年人”的答案——如果有人想要一个自定义实例检查他的异常处理,为什么不让他呢?
    【解决方案2】:

    但是这有什么原因吗 不应该实施吗?

    你能举一个有用的例子吗?

    当你这样做时:

    class SomeMeta(type):
        def __subclasscheck__(cls, sub):
            print (cls, sub)
            return True
    
    class Something(Exception):
        pass
    
    class SomeType(Exception):
        __metaclass__ = SomeMeta
    
    try:
        raise Something()
    except SomeType, e:
        pass
    
    # prints (<class '__main__.SomeType'>, <class '__main__.Something'>)
    

    Python 在SomeType 的元类上调用__subclasscheck__ 以确定Something 是否是SomeType 的子类。 Metaclass PEP 对此进行了更详细的讨论。

    【讨论】:

    • 我现在在 2.6 和 3.2a 上都尝试了你的 __subclasscheck__ 建议,不幸的是它没有奏效。关于您的问题:“具体”是什么意思?一个有用的例子吗?
    • 好的,我看到我们的两个示例在 2.6 中都可以工作,但在 3.1 或 3.2a 中却不行。
    • 关于一个有用的例子:我有一个想法,为异常创建类似abc 的东西,这样你就可以注册一个异常实例作为不同异常类型的实例。这可以防止在捕获异常而引发另一个异常时烦人的回溯隐藏。
    猜你喜欢
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 2021-07-25
    • 2021-07-14
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多