Inheritance uses attribute lookup across a C3-linearized MRO stored in mro
Inheritance in Python is not a copying mechanism. A subclass stores base classes in bases and the interpreter computes a linear order over the class and all its ancestors using the C3 linearization algorithm. That order is stored in Class.mro and is what attribute lookup walks. When you access obj.attr, Python checks type(obj).mro in order for a data descriptor, then the instance dict, then non-data descriptors and class attributes. Method lookup is therefore a linear scan, not a tree walk, which is why cooperative multiple inheritance needs super() rather than explicit base calls.
mro is a tuple; mro() returns a list. Both reflect the same C3 result.
C3 preserves local precedence order and monotonicity, which prevents surprising reordering of ancestors.
super() does not mean the parent; it means the next class after the current one in the instance's MRO.
Trade-off: multiple inheritance gives flexibility but complicates initialization. Cooperative super() with **kwargs is the pattern that keeps it sane.
Common mistake: assuming super() always calls the immediate parent. In multiple inheritance it may skip several classes.
Version note: C3 linearization has been used since Python 2.3 for new-style classes and is the only MRO in Python 3.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience