I was playing around with the multiple inheritance in python and I come a cross a situation that I can't understand how it happen.
Here is the inheritance layout:
A F
/ \ |
B C |
\ | /
\ | /
D
The ABCD diamond that everyone familiar with. Plus an extra class "F" I throw it in for fun.
Here is the code:
class A(object):
def foo(self, call_from):
print "foo from A, call from %s" % call_from
super(A, self).foo("A")
class B(A):
def foo(self, call_from):
print "foo from B, call from %s" % call_from
super(B, self).foo("B")
class C(A):
def foo(self, call_from):
print "foo from C, call from %s" % call_from
super(C, self).foo("C")
class F(object):
def foo(self, call_from):
print "foo from F, call from %s" % call_from
class D(B, C, F):
def foo(self):
print "foo from D"
super(D, self).foo("D")
output:
>>> d = D()
>>> d.foo()
foo from D
foo from B, call from D
foo from C, call from B
foo from A, call from C
foo from F, call from A
The method resolution order:
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.F'>, <type 'object'>)
foo from C, call from B
instead of foo from C, call from D
foo from F, call from A
just simply throw me off...It seems like the super()
are chained up according to the method resolution order and ignore the relationship between classes, but I not sure.
Can someone point me to the right direction to understand this behavior?
Please keep in mind that I'm trying to understand the language itself. Not trying to solve a practical problem. So I don't have an use case for this. But it will be nice if someone can point out an use case :)
UPDATE:
To summarize - super() simply let you know what is next to call base on the mro. It is not necessary the parent. While mro built base on the inheritance hierarchy, mro itself is not the inheritance hierarchy.
Supercharge Your Classes With Python super()Python supports inheritance from multiple classes.
The super() function is used to give access to methods and properties of a parent or sibling class. The super() function returns an object that represents the parent class.
Python super function with multilevel inheritance Well, Python super() will always refer the immediate superclass. Also Python super() function not only can refer the __init__() function but also can call all other function of the superclass. So, in the following example, we will see that.
When you initialize a child class in Python, you can call the super(). __init__() method. This initializes the parent class object into the child class. In addition to this, you can add child-specific information to the child object as well.
The whole point of super()
is to follow the method resolution order. That's why you tell it your own class, not your parent class. It's hard for the programmer to predict which class will be invoked next, so you let super()
take care of it.
You already had B called from D, so how could you then get C called from D? D.foo() can only call one other foo(), because you only have one function call there. It's going to be a linear chain of calls, so the classes have to be linearized, that's what the method resolution order does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With