I have a code here:
class Prey:
def __init__(self):
super().__init__()
print("Prey's init")
class Predator:
def __init__(self):
super().__init__()
print("Predator's init")
class Rabbit(Prey):
def __init__(self):
super().__init__()
print("Rabbit's init")
class Fish(Prey, Predator):
def __init__(self):
super().__init__()
print("Fish's init")
class Hawk(Predator):
def __init__(self):
super().__init__()
print("Hawk's init")
class Creature(Rabbit, Fish, Hawk):
def __init__(self):
super().__init__()
print("Creature's init")
c = Creature()
The Relationship of the above code is here:
Prey Predator
/ \ / \
Rabbit Fish Hawk
\ | /
Creature
And the output of the above code is here:
Predator's init
Hawk's init
Prey's init
Fish's init
Rabbit's init
Creature's init
I need to understand how Method resolution Order works in python and why this specific output? (If someone have some better tutorial you can refer, please feel free to paste the link.) I have some other code which I can't paste it here, so I'm pasting here with a silly example.
The MRO is basically a linearization of a directed acyclic graph. In this case, the nodes of the graph are the classes, and a directed edge connects a class to its parent. There are no cycles, because no class can indirectly inherit from one of its own descendants. A linearization is just a fixed ordering of the classes.
An obvious constraint on this ordering is that if
Ainherits fromB, thenAshould appear beforeB. What's less obvious is how classes not related to each other should be ordered. In order to obey a property known as monotonicity, we require (among other things) that the parents of a class be listed in the same order in the linearization as in the class definition. That is, givennot only does
Aappear beforeBandC, butBmust appear beforeCas well in a monotonic linearization.These two facts alone are sufficient to limit our choices of a monotonic linearization in your example to
So why does Python (or rather, the C3 linearization algorithm) prefer #2 to #1? It imposes an additional constraint, based on "similarity". If
Ais "more like"Bthan likeC, thenBprecedesC. In this case, aCreatureis more like aPreythan aHawk, because it is more like aFishthan aHawk(becauseFishprecedesHawkin the parent list), and aFishis kind ofPrey.