211. Multiple Inheritance Pitfalls

🔹 1. Diamond Problem – Ambiguity in Method Resolution Order (MRO)

class A:
    def greet(self):
        print("Hello from A")

class B(A):
    pass

class C(A):
    def greet(self):
        print("Hello from C")

class D(B, C):
    pass

d = D()
d.greet()  # Hello from C
print(D.mro())  # [D, B, C, A, object]

🔍 Issue:

  • D inherits from both B and C, but C overrides greet.

  • Method Resolution Order (MRO) determines that C's method is called.


🔹 2. MRO Conflicts – Inconsistent Hierarchy

🔍 Issue:

  • The MRO becomes inconsistent when D and E have different base class orders.


🔹 3. Super() Calls in Multiple Inheritance

🔍 Issue:

  • Calls super() correctly based on MRO:

  • This works if all classes use super() correctly.


🔹 4. Using super() Incorrectly

🔍 Issue:

  • A.__init__() gets called twice!

  • Fix this by using super() only if all classes cooperate.


🔹 5. Attribute Name Conflicts

🔍 Issue:

  • Both A and B define value.

  • MRO picks A’s version, potentially leading to bugs.


🔹 6. Overriding Methods in Unexpected Ways

🔍 Issue:

  • The method in C is ignored because B comes first in D(B, C).


🔹 7. Calling Parent Methods Explicitly

🔍 Issue:

  • Bad practice: Calls A.show() twice.

  • Better to use super() to avoid redundant calls.


🔹 8. Using isinstance with Multiple Base Classes

🔍 Issue:

  • isinstance(d, A) is True, even though D never explicitly inherits from A.


🔹 9. Multiple Base Classes with super()

🔍 Correct MRO prevents double initialization:

  • Ensure all classes use super() correctly to prevent duplicate calls.


🔹 10. Avoiding Multiple Inheritance with Composition

🔍 Why this works better?

  • Composition over inheritance avoids MRO issues.

  • More maintainable & modular than multiple inheritance.


🚀 Summary

Pitfall

Issue

Solution

Diamond Problem

MRO ambiguity

Use super() properly

MRO Conflicts

Inconsistent ordering

Follow a clear class hierarchy

Super Calls

Wrong method calls

Ensure all classes use super()

Attribute Conflicts

Overwritten attributes

Use unique attribute names

Method Overriding

Unexpected behavior

Check mro() before overriding

Explicit Parent Calls

Repeating method calls

Use super() instead

isinstance Issues

Inheriting unintended behavior

Avoid unnecessary multiple inheritance

Multiple __init__ Calls

Calls parent multiple times

Use super() correctly

Super in Multiple Base Classes

Wrong super() order

Use cooperative multiple inheritance

Alternative: Composition

Complex MRO issues

Prefer composition over inheritance


🚀 Best Practices

✅ Prefer single inheritance unless multiple inheritance is absolutely needed. ✅ Use MRO (print(Class.mro())) to check method resolution order. ✅ Always use super() to avoid redundant method calls. ✅ Consider composition as an alternative.

Last updated