Morez
Morez

Reputation: 2229

Python Multiple Inheritance super method call

I was reading this article but I cannot understand the following example:

class Class1: 
    def m(self): 
      print("In Class1") 
      print("here1")
  
class Class2(Class1): 
    def m(self): 
        print("In Class2") 
        super().m() 
        print("here2")
  
class Class3(Class1): 
    def m(self): 
        print("In Class3") 
        super().m() 
        print("here3")
  
class Class4(Class2, Class3): 
    def m(self): 
        print("In Class4")    
        super().m() 
       
obj = Class4() 
obj.m() 

The result is:

In Class4
In Class2
In Class3
In Class1
here1
here3
here2

Why is the result printed in that order? I expected the result to be:

In Class4
In Class2
In Class1
here1
here2
In Class3
In Class1
here1
here3

Why is super().m() discarded when we enter Class2? it only runs when we finish printing "In Class3".

Thanks

Upvotes: 0

Views: 101

Answers (2)

Mickey
Mickey

Reputation: 1505

That's because of Python's method resolution order. You can view the MRO of your classes by calling Class4.mro() for example. You will see that Class3 comes before Class1. This is because Python's MRO (https://www.python.org/download/releases/2.3/mro/) uses the C3 Linearization algorithm (https://en.wikipedia.org/wiki/C3_linearization).

Quoting Guido van Rossum (from wikipedia):

Basically, the idea behind C3 is that if you write down all of the ordering rules imposed by inheritance relationships in a complex class hierarchy, the algorithm will determine a monotonic ordering of the classes that satisfies all of them. If such an ordering can not be determined, the algorithm will fail.

You can read into the algorithm, but a simplistic view I like to hold about the alogirthm is this: It's basically a DFS from left to right, but a subclass will always be earlier than it's superclass.

Note: this is a simplistic view of the rule, and it not covers the algorithm nor the failed cases, but in most cases it's a good way to remember the MRO basics.

Upvotes: 1

ConnerWithAnE
ConnerWithAnE

Reputation: 1168

It is printing the the order of all the class locations first because you are calling that super class

def m(self): 
    print("In Class3") 
    super().m() 
    print("here3")

See you are calling super().m() which will cause the parent classes self function to run which holds the print("In Classn") statement in that fucntion, which will then call the next super().m() causing another self function to be ran. You need to print the here before hand.

Upvotes: 0

Related Questions