Posted by: Zeeshan Amjad | October 12, 2023

Multiple Inheritance and Method Resolution Order in Python


Python is one of the few language who support multiple inheritance. Here is a simplest program to demonstrate multiple inheritance in Python.

class Parent1:
    pass

class Parent2:
    pass

class Child(Parent1, Parent2):
    pass

if __name__ == "__main__":
    child = Child()

But what would be the method resolution order if same method is inherited in the class more than one way. The simple way to demonstrate this is to create a based class, inherit two class from it and inherit new class inherited from both, also known as diamond problem. It can be demonstrated by this diagram.

Diamond Problem

Here is a simplest implementation of this.

class GrandParent:
    pass

class Parent1(GrandParent):
    pass

class Parent2(GrandParent):
    pass

class GrandChild(Parent1, Parent2):
    pass

Now if we have a method in GrandParent, it comes twice in the GrandChild class via both parent classes. Let’s create a simple program.

class GrandParent:
    def method(self):
        print("GrandParent.method")

class Parent1(GrandParent):
    def method(self):
        super().method()
        print("Parent1.method")

class Parent2(GrandParent):
    def method(self):
        super().method()
        print("Parent2.method")

class GrandChild(Parent1, Parent2):
    def method(self):
        super().method()
        print("GrandChild.method")

if __name__ == "__main__":
    gc = GrandChild()
    gc.method()

Here is the output of the program

GrandParent.method

Parent2.method

Parent1.method

GrandChild.method

The way Python looks for methods or attributes in the class hierarchy is called Method Resolution Order or simply MRO. Python internally uses C3 Linearization Algorithm to computer MRO in case of multiple inheritance. C3 Linearization algorithms remove any duplicate and uses left to right traversal. Here super().method() inside the GrandChild class first call the Parent1 method then Parent 2. If we changed the order of classes while doing the inheritance then it changes accordingly.

Python also define special method mro to display the current Method Resolution Order. It can be called at class level in two ways. Here is a simple code to demonstrate the MRO

class GrandParent:
    def method(self):
        print("GrandParent.method")

class Parent1(GrandParent):
    def method(self):
        super().method()
        print("Parent1.method")

class Parent2(GrandParent):
    def method(self):
        super().method()
        print("Parent2.method")

class GrandChild(Parent1, Parent2):
    def method(self):
        super().method()
        print("GrandChild.method")

if __name__ == "__main__":
    gc = GrandChild()
    print(GrandChild.mro())
    print(GrandChild.__mro__)

Here is the output of this program that shows MRO.

[<class ‘__main__.GrandChild’>, <class ‘__main__.Parent1’>, <class ‘__main__.Parent2’>, <class ‘__main__.GrandParent’>, <class ‘object’>]

(<class ‘__main__.GrandChild’>, <class ‘__main__.Parent1’>, <class ‘__main__.Parent2’>, <class ‘__main__.GrandParent’>, <class ‘object’>) 


Leave a comment

Categories