玩isinstance
,我想知道它是如何用于子类检查的。
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?
type((和isinstance((之间有什么区别?解释了isinstance
确实适用于子类,如我的第二条和第三条print
语句所示。我的问题不是,但是,它是如何工作的?当类别A
被定义时,它没有关于类别B
或类别C
的存在的信息,同样地,B
没有关于C
的信息。
根据"如何为List工作?"?__instancecheck__
是为isinstance
调用的,所以如果我的类A
是在B
和C
之前创建的,这个Python怎么知道C()
确实是其中一个子类(B
,A
的子类(或A
的子类(C
,B
的子类,本身也是A
的一个子类(的实例?
当我在Python中继承一个类,使得基类知道存在子类时,会发生什么事情吗?如果是这样的话,有人能告诉我这是怎么回事吗?
附言:如果需要澄清,请告诉我。非常感谢。
C()
拥有对其类型C
的引用,而C
拥有其所有祖先(包括其自身(的元组C.__mro__
。默认的type.__instancecheck__
通过该元组查看对象是否是特定类的实例。
如果你按照type.__instancecheck__
的函数调用,你最终会进入这个循环:
for (i = 0; i < n; i++) {
if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b)
return 1;
Python中的类也有关于其子类的信息-C级PyType_Ready
函数在准备子类时通知基类关于子类。然而,对于isinstance
的第二个自变量有很多后代的情况,从基类向下搜索继承图会产生病态的缓慢行为。
基类不需要知道其他类对它的继承。当您在C()
上调用isinstance()
时,它是B的子类(a的子类(,它会创建从C向上的继承树(一直到作为每个类的基类的对象(。然后它";知道";A和B在那里。你定义A、B、C的顺序没有任何意义。