Some programming languages, such as Python, C++, etc, allow classes to inherit multiple other classes (i.e. allow multiple inheritance).

Hence, when we inherit multiple classes from another, different types of inheritance patterns can be formed.

However, one pattern of inheritance in programming languages that resembles a diamond shape cause ambiguity in the call to the parent class method, which is popularly known as the diamond problem.

In this tutorial, we will learn what actually the diamond problem is and how can we resolve it in Python.

What is Diamond Problem?

The diamond problem occurs when two classes have a common parent class, and another class has both those classes as base classes.

inheritance pattern that causes the diamond problem

IIn this kind of implementation of inheritance, if class B and class C override (any) same method of class A and instance of class D calls that method, it becomes ambiguous to programming languages, whether we want to call the overridden method from class B or the one from class C.

For example:

class A:
    def display(self):
        print("This is class A")
        
class B(A):
    def display(self):
        print("This is class B")
        
class C(A):
    def display(self):
        print("This is class C")
        
class D(B, C):
    pass

obj = D()
obj.display()

In this code example, we are calling display method on the instance of class D. As class D inherits both class B and class C, it is unknown which of the overridden display will be called by Python interpreter.

How to Solve Diamond Problem in Python?

Because of the method resolution order (__mro__) in Python, the ambiguity of the diamond problem in Python becomes irrelevant.

The method resolution order in Python is the order in which a method is searched for in the class hierarchy, in case of inheritance.

We can view this order by accessing the __mro__ attribute on the classes.

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

As we can see, in the __mro__ output of class D, the class B comes before class C. Therefore, if call the display method on class D the Python interpreter will find and invoke the display method of class B.

>>> obj.display()
This is class B

When we inherit from multiple classes, and if their method name conflicts, then the first-class name takes precedence. This is the reason why, class B is before class C in the order of __mro__.

Adarsh Kumar

I am an engineer by education and writer by passion. I started this blog to share my little programming wisdom with other programmers out there. Hope it helps you.

Leave a Reply