Super confusing multiple inheritance python super ()

I played with multiple inheritance in python, and I am in a situation where I cannot figure out how this happens.

Here is the inheritance layout:

AF / \ | BC | \ | / \ | / D 

Diamond ABCD everyone is familiar with. Plus an extra “F” class. I drop it 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") 

exit:

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

Method resolution procedure:

 >>> 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 drop me ...

It seems that super() bound according to the order of resolution of the method and ignore the relationship between the classes, but I'm not sure.

Can someone point me in the right direction to understand this behavior?

Please keep in mind that I am trying to understand the language itself. Do not try to solve a practical problem. Therefore, I have no precedent. But it will be good if someone can specify an example of use :)


UPDATE:

To summarize - super () will just tell you what's next to the call base on mro. Parent is not needed. While mro is built around an inheritance hierarchy, mro itself is not an inheritance hierarchy.

+8
python inheritance super methods
source share
2 answers

The whole point of super() is to follow the order in which the method is resolved. That is why you tell him your own class, not your parent class. It's hard for a programmer to predict which class will be called next, so you can super() take care of that.

You have already called B from D, so how could you get C from D? D.foo () can only call one other foo (), because there is only one function call there. This will be a linear chain of calls, so classes must be linearized, which makes the method resolution order.

+7
source share

Sometimes it seems to me useful to call super for the parent class. Example.

 class TmpClass0(object): def tmp_method(self): print 'TmpClass0 tmp_method' class TmpClass1(TmpClass0): def tmp_method(self): print 'TmpClass1 tmp_method' 

Now I want to use TmpClass0 tmp_method from an instance of TmpClass2.

 class TmpClass2(TmpClass1): def tmp_method(self): super(TmpClass1, self).tmp_method() 

Result:

 In [107]: tmp_class2 = TmpClass2() In [108]: tmp_class2.tmp_method() TmpClass0 tmp_method 
+1
source share

All Articles