简体   繁体   English

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

[英]How does isinstance work in python for subclasses?

Playing around with isinstance , I would like to know how it works for a subclass check.玩弄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?

What are the differences between type() and isinstance()? type() 和 isinstance() 有什么区别? explains that isinstance does work for a subclass as seen in my second and third print statement.解释说isinstance确实适用于我的第二个和第三个print语句中的子类。 My question is not that, but, how does it work?我的问题不是那个,而是,它是如何工作的? When class A was defined it had no information but about the existence of class B or class C , likewise B had no information about C . When class A was defined it had no information but about the existence of class B or class C , likewise B had no information about C .

According to How does isinstance work for List?根据isinstance 如何为 List 工作? __instancecheck__ is called for isinstance , so if my class A was created before B and C how does this Python know that C() is indeed an instance of one of the subclass ( B , subclass of A ) or subclass of subclass of A ( C , which is a subclass of B which itself is a subclass of A )? __instancecheck__ is called for isinstance , so if my class A was created before B and C how does this Python know that C() is indeed an instance of one of the subclass ( B , subclass of A ) or subclass of subclass of A ( C ,哪个是B的子类,它本身是A的子类)?

Does something happen when I inherit a class in Python such that the base class knows that a child class exists?当我在 Python 中继承 class 以使基础 class 知道子 ZA2F2ED4F8EBC2CBBD4C21A26 存在时,会发生什么事情吗? If that is the case can anyone let me know how this works?如果是这种情况,谁能告诉我这是如何工作的?

PS: Do let me know if any clarification is needed. PS:如果需要任何澄清,请告诉我。 Many Thanks.非常感谢。

C() holds a reference to its type, C , and C has a tuple C.__mro__ of all its ancestors (including itself). C()持有对其类型C的引用,并且C有一个元组C.__mro__的所有祖先(包括它自己)。 The default type.__instancecheck__ looks through that tuple to see whether an object is an instance of a particular class.默认type.__instancecheck__会查看该元组以查看 object 是否是特定 class 的实例。

If you follow the function calls down from type.__instancecheck__ , you eventually end up in this loop :如果您遵循 function 从type.__instancecheck__向下调用,您最终会进入此循环

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

Classes in Python do also have information about their subclasses - the C-level PyType_Ready function informs the base classes about a subclass while readying the subclass. Python的类也有关于其子类的信息——C 级PyType_Ready function 在准备子类时通知基类关于子类。 However, searching the inheritance graph downward from the base class would produce pathologically slow behavior for cases where the second argument to isinstance has a lot of descendants.但是,对于isinstance的第二个参数有很多后代的情况,从基础 class 向下搜索 inheritance 图会产生病态缓慢的行为。

The base class doesn't need to know anything about it's inheritance by other classes.基础 class 不需要知道其他类的 inheritance 的任何信息。 When you call the isinstance() on C() , which is a subclass of B (which is a subclass of A) it creates the inheritance tree from C upwards (all the way to object which is the base class of every class). When you call the isinstance() on C() , which is a subclass of B (which is a subclass of A) it creates the inheritance tree from C upwards (all the way to object which is the base class of every class). It then "knows" that A and B are there.然后它“知道” A 和 B 在那里。 The order in which you defined A,B,C doesn't have any meaning.您定义 A,B,C 的顺序没有任何意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM