Understanding Multiple Inheritance Method Resolution Order in Python
This code demonstrates how Python's MRO determines which greet method is called in a diamond inheritance scenario, and prints the full MRO for class D.
Python code
20 linesclass A:
def greet(self):
return "Hello from A"
class B(A):
def greet(self):
return "Hello from B"
class C(A):
def greet(self):
return "Hello from C"
class D(B, C):
pass
if __name__ == "__main__":
d = D()
print(d.greet())
print(D.__mro__)
Output
Hello from B
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
How it works
Python uses the C3 linearization algorithm to compute the Method Resolution Order (MRO) for classes with multiple inheritance. In this example, class D inherits from both B and C, creating a diamond pattern. The MRO ensures that each class appears exactly once and that the order is consistent with the inheritance dependencies, so B is prioritized over C because B appears first in D's base list. The __mro__ attribute shows the full lookup order, which is why d.greet() resolves to B's method before C's or A's. This deterministic ordering prevents ambiguity in method resolution.
Common mistakes
- Assuming MRO follows the order of the base classes in the class definition plus a left-to-right depth-first search without accounting for C3 linearization.
- Forgetting that the MRO includes all ancestor classes and 'object' at the end.
- Expecting that the most specific base class always wins; in diamond inheritance, the order of bases can matter.
Variations
- Use `super()` to cooperatively call methods up the MRO.
- Inspect `D.mro()` (without underscores) to get the same list programmatically.
Real-world use cases
- Designing mixin classes where method precedence must be predictable to avoid unexpected overrides.
- Building class hierarchies that combine multiple behavior sources while maintaining consistent method resolution.
- Debugging complex OOP codebases to trace which method is actually called in a diamond-style inheritance.
Sponsored
More from OOP & classes
- Add property getter setter validation in Python easy
- Binary Tree Inorder Traversal in Python easy
- Borg pattern shared state in Python medium
- Bridge Pattern in Python: Separate Abstraction from Implementation medium
- Composable Predicates with the &, |, ~ Operators in Python medium
- Composition over Inheritance: How to Build a Wallet Account in Python easy
Keep learning
Related tutorials and quizzes for this topic.