Python Multiple Inheritance

Summary: in this tutorial, you’ll learn about Python multiple inheritance and how method order resolution works in Python.

Introduction to the Python Multiple inheritance.

When a class inherits from a single class, you have single inheritance. Python allows a class to inherit from multiple classes. If a class inherits from two or more classes, you’ll have multiple inheritance.

To extend multiple classes, you specify the parent classes inside the parentheses () after the class name of the child class like this:

class ChildClass(ParentClass1, ParentClass2, ParentClass3):
   passCode language: Python (python)

The syntax for multiple inheritance is similar to a parameter list in the class definition. Instead of including one parent class inside the parentheses, you include two or more classes, separated by a comma.

Let’s take an example to understand how multiple inheritance works:

Python Multiple Inhertiance

First, define a class Car that has the go() method:

class Car:
    def go(self):
        print('Going')Code language: Python (python)

Second, define a class Flyable that has the fly() method:

class Flyable:
    def fly(self):
        print('Flying')Code language: Python (python)

Third, define the FlyingCar that inherits from both Car and Flyable classes:

class FlyingCar(Flyable, Car):
    passCode language: Python (python)

Since the FlyingCar inherits from Car and Flyable classes, it reuses the methods from those classes. It means you can call the go() and fly() methods on an instance of the FlyingCar class like this:

if __name__ == '__main__':
    fc = FlyingCar()
    fc.go()
    fc.fly()Code language: Python (python)

Output:

Going
FlyingCode language: Python (python)

Method resolution order (MRO)

When the parent classes have methods with the same name and the child class calls the method, Python uses the method resolution order (MRO) to search for the right method to call. Consider the following example:

First, add the start() method to the Car, Flyable, and FlyingCar classes. In the start() method of the FlyingCar class, call the start() method of the super():

class Car:
    def start(self):
        print('Start the Car')

    def go(self):
        print('Going')


class Flyable:
    def start(self):
        print('Start the Flyable object')

    def fly(self):
        print('Flying')


class FlyingCar(Flyable, Car):
    def start(self):
        super().start()Code language: Python (python)

Second, create an instance of the FlyingCar class and call the start() method:

if __name__ == '__main__':
    car = FlyingCar()
    car.start()Code language: Python (python)

Output:

Start the Flyable objectCode language: Python (python)

As you can see clearly from the output, the super().start() calls the start() method of the Flyable class.

The following shows the __mro__ of the FlyingCar class:

print(FlyingCar.__mro__)Code language: Python (python)

Output:

(<class '__main__.FlyingCar'>, <class '__main__.Flyable'>, <class '__main__.Car'>, <class 'object'>)Code language: Python (python)

From left to right, you’ll see the FlyingCar, Flyable, Car, and object.

Note that the Car and Flyable objects inherit from the object class implicitly. When you call the start() method from the FlyingCar‘s object, Python uses the __mro__ class search path.

Since the Flyable class is next to the FlyingCar class, the super().start() calls the start() method of the FlyingCar class.

If you flip the order of Flyable and Car classes in the list, the __mro__ will change accordingly. For example:

# Car, Flyable classes...


class FlyingCar(Car, Flyable):
    def start(self):
        super().start()


if __name__ == '__main__':
    car = FlyingCar()
    car.start()

    print(FlyingCar.__mro__)Code language: Python (python)

Output:

Start the Car
(<class '__main__.FlyingCar'>, <class '__main__.Car'>, <class '__main__.Flyable'>, <class 'object'>)Code language: Python (python)

In this example, the super().start() calls the start() method of the Car class instead, based on their orders in the method order resolution.

Multiple inheritance & super

First, add the __init__ method to the Car class:

class Car:
    def __init__(self, door, wheel):
        self.door = door
        self.wheel = wheel

    def start(self):
        print('Start the Car')

    def go(self):
        print('Going')Code language: Python (python)

Second, add the __init__ method to the Flyable class:

class Flyable:
    def __init__(self, wing):
        self.wing = wing

    def start(self):
        print('Start the Flyable object')

    def fly(self):
        print('Flying')Code language: Python (python)

The __init__ of the Car and Flyable classes accept a different number of parameters. If the FlyingCar class inherits from the Car and Flyable classes, its __init__ method needs to call the right __init__ method specified in the method order resolution __mro__ of the FlyingCar class.

Third, add the __init__ method to the FlyingCar class:

class FlyingCar(Flyable, Car):
    def __init__(self, door, wheel, wing):
        super().__init__(wing=wing)
        self.door = door
        self.wheel = wheel

    def start(self):
        super().start()Code language: Python (python)

The method order resolution of the FlyingCar class is:

(<class '__main__.FlyingCar'>, <class '__main__.Flyable'>, <class '__main__.Car'>, <class 'object'>)Code language: Python (python)

the super().__init__() calls the __init__ of the FlyingCar class. Therefore, you need to pass the wing argument to the __init__ method.

Because the FlyingCar class cannot access the __init__ method of the Car class, you need to initialize the doorand wheel attributes individually.

Summary

  • Python multiple inheritance allows one class to inherit from multiple classes.
  • The method order resolution defines the class search path to find the method to call.
Did you find this tutorial helpful ?