Reputation: 2229
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
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
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