gpt4 book ai didi

python - 为什么引发异常会调用 __subclasscheck__?

转载 作者:行者123 更新时间:2023-12-03 23:44:12 26 4
gpt4 key购买 nike

考虑以下使用 __subclasscheck__ 的示例对于自定义异常类型:

class MyMeta(type):
def __subclasscheck__(self, subclass):
print(f'__subclasscheck__({self!r}, {subclass!r})')

class MyError(Exception, metaclass=MyMeta):
pass
现在,当引发这种类型的异常时, __subclasscheck__方法被调用;即 raise MyError()结果是:
__subclasscheck__(<class '__main__.MyError'>, <class '__main__.MyError'>)
Traceback (most recent call last):
File "test.py", line 8, in <module>
raise MyError()
__main__.MyError
这里输出的第一行显示 __subclasscheck__被调用以检查是否 MyError是自身的子类,即 issubclass(MyError, MyError) .我想了解为什么这是必要的以及它通常是如何有用的。

我正在使用 CPython 3.8.1 来重现这种行为。我也试过 PyPy3 (3.6.9) 和这里 __subclasscheck__不被调用。

最佳答案

我想这是一个 CPython 实现细节。如文档所述 PyErr_NormalizeException :

Under certain circumstances, the values returned by PyErr_Fetch()below can be “unnormalized”, meaning that *exc is a class object but*val is not an instance of the same class.


所以在处理引发的错误的某个时候,CPython 会规范化异常,否则它无法假设错误的值是正确的类型。
在你的情况下,它发生如下:
  • 最终在处理异常时, PyErr_Print 被调用,它在哪里calls _PyErr_NormalizeException .
  • _PyErr_NormaliizeException calls PyObject_IsSubclass .
  • PyObject_IsSubclass 用途 __subclasscheck__如果提供。

  • 我不能说“ *exc 是类对象但 *val 不是同一类的实例”的那些“某些情况”是什么(可能需要向后兼容 - 我不知道)。

    我的第一个假设是,它发生在 CPython 确保(即 here )时,异常源自 BaseException .
    以下代码
    class OldStyle():
    pass

    raise OldStyle
    会提出 OldStyle对于 Python2,但是 TypeError: exceptions must be old-style classes or derived from BaseException, not type为了
    class NewStyle(object):
    pass

    raise NewStyle
    TypeError: exceptions must derive from BaseException在 Python3 中,因为在 Python3 中所有类都是“新风格”。
    但是,对于此检查不是 PyObject_IsSubclass但是 PyType_FastSubclass 用来:
    #define PyExceptionClass_Check(x)                                       \
    (PyType_Check((x)) && \
    PyType_FastSubclass((PyTypeObject*)(x), Py_TPFLAGS_BASE_EXC_SUBCLASS))
    即只有 tpflag s被看着。

    关于python - 为什么引发异常会调用 __subclasscheck__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63928368/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com