Let's have the following Python2 code:
#!/usr/bin/python
class A1(object):
def __init__(self):
super(A1, self).__init__()
print "A1.__init__"
class A2(A1):
def __init__(self):
super(A2, self).__init__()
print "A2.__init__"
class B1(object):
def __init__(self):
super(B1, self).__init__()
print "B1.__init__"
class B2(B1):
def __init__(self):
super(B2, self).__init__()
print "B2.__init__"
class C(A2, B2):
def __init__(self):
super(C, self).__init__()
print "C.__init__"
C()
print C.mro()
That is, C
inherits from two predecessor class branches, which have no mutual ancestor (except for the default object
, not sure how important this is). The code outputs:
B1.__init__
B2.__init__
A1.__init__
A2.__init__
C.__init__
[<class '__main__.C'>, <class '__main__.A2'>, <class '__main__.A1'>, <class '__main__.B2'>, <class '__main__.B1'>, <type 'object'>]
Exactly as expected.
Now say that I'm careless and forget to call super().__init__()
in A1
and B1
(I don't care about initializing object
that much...). The output then changes to:
A1.__init__
A2.__init__
C.__init__
[<class '__main__.C'>, <class '__main__.A2'>, <class '__main__.A1'>, <class '__main__.B2'>, <class '__main__.B1'>, <type 'object'>]
Now only the A1
-A2
branch was initialized - while C.mro()
had not changed at all!
What is the reason of this behavior?
The printout of the MRO shows you exactly why this is. Python calls the parent methods in that specific order, hence the name. It calls A2's method, which has a super call so then calls A1's method; but A1 does not in turn call super so the chain stops there.