The MRO (Method Resolution Order) for the Animal class is calculated using the C3 linearization algorithm, which takes into account the order of inheritance and resolves any conflicts that arise, even if you call one of the constructors explicitly:
class Animal(canFly, canSwim, canWagTail):
def __init__(self, name):
canFly.__init__(self, name)
In this case, the Animal class inherits from the canFly, canSwim, and canWagTail classes, which in turn inherit from the Mammal class. The C3 linearization algorithm determines the MRO for the Animal class as follows:
Animal
canFly
canSwim
canWagTail
Mammal
object
This means that when the Animal class is instantiated with the argument "Dog", the __init__ methods of its superclasses are called in the following order:
__init__ method of canFly: prints "Dog cannot fly" and calls the __init__ method of its next class in the MRO, which is canSwim.
__init__ method of canSwim: prints "Dog cannot swim" and calls the __init__ method of its next class in the MRO, which is canWagTail.
__init__ method of canWagTail: prints "Dog can wag tail" and calls the __init__ method of its next class in the MRO, which is Mammal.
__init__ method of Mammal: prints "Dog Is a mammal".
Therefore, even though only the __init__ method of the canFly class is called explicitly, the MRO ensures that the __init__ methods of all the superclasses are called in the order determined by the C3 linearization algorithm.
I'm not sure it makes a lot of sense to inherit without actually using the constructor but you could modify the __init__ method of the canSwim and canWagTail classes to accept a boolean flag indicating whether to call the superclass constructor or not. If the flag is set to False, the constructor will skip calling the superclass constructor.
Here's an example of how you can modify the canSwim and canWagTail classes:
class canSwim(Mammal):
def __init__(self, canSwim_name, call_super=True):
if call_super:
print(canSwim_name, "cannot swim")
super().__init__(canSwim_name)
class canWagTail(Mammal):
def __init__(self, canWag_name, call_super=True):
if call_super:
print(canWag_name, "can wag tail")
super().__init__(canWag_name)
Then, in the __init__ method of the Animal class, you can call the canFly constructor and pass False for the call_super parameter for the canSwim and canWagTail constructors, like this:
class Animal(canFly, canSwim, canWagTail):
def __init__(self, name):
canFly.__init__(self, name)
canSwim.__init__(self, name, False)
canWagTail.__init__(self, name, False)
Then you should get your desired output:
Dog cannot fly
Dog Is a mammal
Hope this helps :)