Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MRO with multiple inheritance in python

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?

like image 581
JasperTack Avatar asked Jun 11 '26 00:06

JasperTack


1 Answers

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__.

like image 173
unutbu Avatar answered Jun 13 '26 07:06

unutbu