isinstance 如何在 python 中为子类工作?

How does isinstance work in python for subclasses?

isinstance,我想知道子 class 检查它是如何工作的。

class A:
    pass

class B(A):
    pass

class C(B):
    pass

print(isinstance(C(), C)) # True, I understand this fine
print(isinstance(C(), B)) # True, Ok, but how is this `True`?
print(isinstance(C(), A)) # True, this too?

What are the differences between type() and isinstance()? 解释说 isinstance 确实适用于 subclass,如我的第二个和第三个 print 语句所示。我的问题不是那个,而是它是如何工作的?当 class A 被定义时,除了 class B 或 class C 的存在之外,它没有任何信息,同样 B没有关于 C.

的信息

根据 __instancecheck__ 被称为 isinstance,所以如果我的 class A 是在 BC这个Python怎么知道C()确实是subclass之一的实例(B,subclass of A) 或 subclass of subclass of A (C,它是 B 的 subclass,它本身是一个 subclass 共 A)?

当我在 Python 中继承了一个 class 时,是否发生了什么事情使得基础 class 知道 child class 存在?如果是这样的话,谁能告诉我这是怎么回事?

PS :如果需要任何说明,请告诉我。非常感谢。

基 class 不需要知道其他 class 继承它的任何信息。 当你在 C() 上调用 isinstance() 时,它是 B 的子class(它是 A 的子class),它会从 C 向上创建继承树(所有对象的方式是每个 class 的基础 class)。 然后它“知道”A 和 B 在那里。 你定义A,B,C的顺序没有任何意义。

C() 持有对其类型的引用,C,并且 C 拥有其所有祖先(包括其自身)的元组 C.__mro__。默认 type.__instancecheck__ 查看该元组以查看对象是否是特定 class.

的实例

如果您按照 type.__instancecheck__, you eventually end up in this loop 的函数调用向下:

for (i = 0; i < n; i++) {
    if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b)
        return 1;

类 in Python do 也有关于它们的子class的信息——C级PyType_Ready函数informs 基地 class 在准备潜艇 class 时正在考虑潜艇 class。但是,如果 isinstance 的第二个参数有很多后代,从基础 class 向下搜索继承图会产生病态的缓慢行为。