class Animal:
    def set_health(self, health):
        print("Set in Animal")

class Carnivour(Animal):
    def set_health(self, health):
        print("Set in Canivour")

class Mammal(Animal):
    def set_health(self,health):
        print("Set in Mammal")

class Dog(Carnivour, Mammal):
    def set_health(self, health):

    print("Set in dog")

dog = Dog()

I know that Python reads this structure of code from left to right. But I can not understand how it changes the output when we swap the Carnivour with Mammal in Dog() class.

Could someone explain me in details how it reads the code that the output prints

Set in animal
Set in Mammal
Set in Carnivour
Set in dog

When we have the Carnivour first in Dog() class

Thanks for help and understanding

🟢 Solution

You're looking for method resolution order or MRO (Linked article is for Python 2.3 but, unlike most Python-2-centric articles this one is actually still relevant today). When you have multiple inheritance, Python linearizes the inheritance hierarchy to figure out where super should go. In your case, in the code you posted, the MRO is

Dog < Carnivour < Mammal < Animal

If you swap the order of inheritance in Dog, you get

Dog < Mammal < Carnivour < Animal

Since you make your "recursive" super call before printing, the print statements appear in the opposite order as the inheritance hierarchy.

You can read all about the details of the C3 linearization algorithm used for MRO in Python in the link above, but the basic idea is: Always follow the leftmost subclass first, unless doing so makes something nonsensical happen, where "something nonsensical" effectively means "a superclass appears before its subclass in the linearization".