How to use super to initialize all parents when using multiple inheritance

How does Python super () with multiple inheritance work?

I looked at the above question / answers and was very confused

53 class First(object): 54 def __init__(self): 55 print "first" 56 57 class Second(First): 58 def __init__(self): 59 super(Second, self).__init__() 60 print "second" 61 62 class Third(First): 63 def __init__(self): 64 print "third" 65 66 class Fourth(Second, Third): 67 def __init__(self): 68 super(Fourth, self).__init__() 69 print "thats it" 

Fourth()
third
second
thats it

  53 class First(object): 54 def __init__(self): 55 print "first" 56 57 class Second(First): 58 def __init__(self): 59 #super(Second, self).__init__() <---- commented out 60 print "second" 61 62 class Third(First): 63 def __init__(self): 64 print "third" 65 66 class Fourth(Second, Third): 67 def __init__(self): 68 super(Fourth, self).__init__() 69 print "thats it" 

Fourth()
second
thats it

Can someone explain to me what is going on behind the scenes as to why the top prints are "third" and the bottom is not?

I feel that there is some kind of order / sequence that occurs behind the scene that I do not see.

- The fourth. mro

commented super in the second (,,)

super in the second
(,,)

+6
source share
2 answers

super doesn't actually call a superclass. It calls the following method in accordance with the method resolution order (MRO). It looks like the MRO for your class classes is as follows:

 Fourth Second Third First 

That is, using super from Fourth , you will get a method on Second . Using super from Second , you get the method on Third . and etc.

In the first example:

  • Fourth.__init__ .
  • Fourth.__init__ calls Second.__init__ via super .
  • Second.__init__ calls Third.__init__ via super .
  • Third.__init__ prints "third"
  • Second.__init__ prints "second"
  • Fourth.__init__ prints "what is it."

In the second example:

  • Fourth.__init__ .
  • Fourth.__init__ calls Second.__init__ via super .
  • Second.__init__ prints "second"
  • Fourth.__init__ prints "what is it."

So yes, changing the call of super to Second changes whether something is called in Third , although Third not a superclass of Second . This is really confusing. I recommend reading "Python Super is great, but you can't use it . " This explanation that I read made sense to me.

+4
source

MRO is not a nested hierarchy. This is a flat list that obeys a set of constraints, namely that each class must precede its base classes, and these base classes must exist in the same order relative to each other, as they are mentioned in the subclass declaration.

Fourth.__mro__ printed Fourth.__mro__ , we see that MRO in your examples:

 (<class '__main__.Fourth'>, <class '__main__.Second'>, <class '__main__.Third'>, <class '__main__.First'>, <type 'object'>) 

Each super call that is called will call the next method in the MRO. You can think of the number of super calls as the zero indexed "depth" in the MRO that you will exit.

Since there are two super calls in the first fragment, Second.__init__ and Third.__init__ (in addition, of course, to the method of the immediate init class). Similarly, in the second snippet, you have one call to super , which means that only Second.__init__ will be called.

+3
source

Source: https://habr.com/ru/post/955923/


All Articles