Reputation: 2076
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?
Upvotes: 0
Views: 38
Reputation: 2076
Okay, to answer my own question: the thing that confused me (failing to call super()
in a class that inherits directly form object
) is described here in detail:
https://fuhm.net/super-harmful/
Upvotes: 0
Reputation: 599620
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.
Upvotes: 2