Loading Page Content...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
Preparing courses, live labs, and learning resources.सामग्री लोड हो रही है, कृपया प्रतीक्षा करें...
In complex object-oriented systems with multiple inheritance, determining which parent version of a method executes is not always trivial. Python resolves method lookups deterministically using the Method Resolution Order (MRO), calculated via the sophisticated C3 Linearization Algorithm. Understanding MRO is essential for mastering cooperative multiple inheritance, mixins, and large Python frameworks.
The classic dilemma in multiple inheritance is the Diamond Problem:
+------------------+
| Class A |
| def action() |
+------------------+
/ \
/ \
+------------------+ +------------------+
| Class B | | Class C |
| def action() | | def action() |
+------------------+ +------------------+
\ /
\ /
+------------------+
| Class D |
| (B, C) |
+------------------+If Class D inherits from both B and C, and all three define action(), which method should execute when calling D().action()?
A would be visited before C, meaning A's outdated base method could override C's specialized method!You can inspect the linear resolution order of any class using two attributes:
ClassName.__mro__: Returns a tuple of classes in resolution order.ClassName.mro(): Returns the same order as a list.Python searches classes strictly from left to right along this sequence: D $\rightarrow$ B $\rightarrow$ C $\rightarrow$ A $\rightarrow$ object.
The C3 algorithm guarantees three fundamental properties:
class D(B, C), class B is always evaluated before class C.X precedes class Y in the MRO of any parent class, X will precede Y in the MRO of any derived class.$$L[C(B_1, B_2, \dots, B_N)] = C + \text{merge}(L[B_1], L[B_2], \dots, L[B_N], (B_1, B_2, \dots, B_N))$$
The merge operation inspects the head of each candidate list. If a head class is not present in the tail (any position other than the first) of any other list, it is extracted and appended to the MRO output.
super() is NOT "Call Parent"—It is "Call Next in MRO"!One of the most widespread misconceptions in Python is that super() simply calls the direct parent class.
super() actually calls the NEXT class in the active MRO sequence of the originating instance!
Notice how super() in class B actually calls class C (its sibling!), not its parent A:
A's call to super().ping() invoked B.ping()! This cooperative dispatch pattern enables multi-tiered mixin architectures without hardcoded dependencies.
If an inheritance hierarchy violates the local precedence rules, the C3 merge algorithm fails, and Python refuses to create the class with a TypeError:
super() with Direct Base Class CallsCalling Parent.__init__(self) directly in multiple inheritance violates C3 Linearization and causes common ancestor constructors to be invoked multiple times in diamond hierarchies. Always use cooperative super().__init__().
Cooperative multiple inheritance requires that all participating classes accept consistent arguments or forward extra arguments with *args, **kwargs.
Construct a classic diamond inheritance hierarchy with classes A, B(A), C(A), and D(B, C). Use cooperative super() calls and inspect D.__mro__.
class D(B, C): pass, what does D.__mro__ return?super() actually invoke in Python?class D(B, C) where both B and C inherit from A, why does C execute before A in the MRO?In the next lesson, we will continue your advanced Python journey with Multiple Inheritance (1: Advanced OOP Concepts).
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
| Previous Lesson | Next Lesson |
|---|---|
| Property Decorator | Multiple Inheritance |
Test your understanding of this lesson with 5 questions. Each question has one correct answer.