MRO with multiple inheritance in python

穿精又带淫゛_ 提交于 2019-12-24 02:33:15

问题


In the documentation on the Python webpage the method resolution order for classic classes in python is described as a depth-first left-to-right search. I tried to test this with this piece of code:

class A(object):
def __init__(self):
    print "Initialized A"

class B(A):
    def test():
        print "Initialized B"

class C(A):
    def __init__(self):
        print "Initialized C"

class D(B, C):
    def __init__(self):
        super(D, self).__init__()
        print "Initialized D"

When I create an instance of object D:

D()

I get the result:

Initialized C
Initialized D

While I expected the prints "Initialized A", "Initialized D" since the MRO is depth-first, the initialization is first searched in B, when not found (which is the case) it should go deeper in the hierarchy and look for the function in the base class of B (i.e. A). Can someone give me an explanation why I get the init-function of C instead of that one of A?


回答1:


Your class inherits from object and is thus not a classic class. It is a new-style class. (Any class that inherits from a new-style class is also a new-style class.)

Note that super can't be used with classic classes anyway. The "depth first left to right" rule you cite is just the attribute lookup rule for the order base classes are searched when you try to access an attribute that is not directly defined on the instance. Classic classes don't provide an MRO as such --- there isn't any way to access "the superclass value" of an attribute without explicitly referencing a particular superclass.




回答2:


The MRO of D is:

print(D.mro())
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]

So

super(D, self).__init__()

looks for an __init__ method in the first class in self.__class__.mro() after D. Since B does not have an __init__, it then looks for an __init__ method in C. It finds C.__init__, and therefore

super(D, self).__init__()

calls C.__init__(self).

Notice that super is not trying to access getattr(B, __init__). Rather, it is looking for '__init__' in B.__dict__.



来源:https://stackoverflow.com/questions/14165923/mro-with-multiple-inheritance-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!