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 :)