sakuew2
sakuew2

Reputation: 81

How do I initialize this derived class that uses multiple inheritance?

Say I have a class called Vehicle, and I have two sub classes called Boat and Car, which inherit from Vehicle.

Now say I have an amphibious vehicle, which uses multiple inheritance AmphibiousVehicle(Boat, Car).

Now my question is: how should the __init__ function of AmphibiousVehicle be defined?

Both Boat and Car initialize Vehicle with a call to super().__init__().

Do I need to initialize Boat and Car one by one in the init of AmphibiousVehicle?

Or can I just call super once? If I do that, I don't see how Car gets initialized?

Upvotes: 1

Views: 377

Answers (1)

SpoonMeiser
SpoonMeiser

Reputation: 20397

Python uses cooperative multiple inheritance. That means that your call to super() doesn't necessarily hit the base class of where it's called, it hits the next class in the method resolution order (MRO) from where you started.

To demonstrate:

class A:
    def __init__(self):
        print("A.__init__")
        super().__init__()

class B:
    def __init__(self):
        print("B.__init__")
        super().__init__()

class C(A, B):
    def __init__(self):
        print("C.__init__")
        super().__init__()

c = C()

Gives the output:

C.__init__
A.__init__
B.__init__

So the call super().__init__() inside class A calls __init__() in class B, even though class A does not inherit from class B.

So long as all your classes make sure they call super where appropriate, you only need to call it once and trust that everything will cooperate.

The MRO is basically the order in which python will search the classes for a method or attribute. You can examine what this order is by inspecting the __mro__ attribute on a class:

print(C.__mro__)

Gives us:

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

Upvotes: 2

Related Questions