Explain Python's MRO, how super() works, and the diamond problem.
Python's Method Resolution Order (MRO) determines which class's method is called when a name is looked up in an inheritance hierarchy. For single inheritance, this is trivial. For multiple inheritance, Python uses C3 linearization, an algorithm that produces a consistent, predictable linear ordering of all classes in the hierarchy.
The diamond problem is the motivating case: class D inherits from B and C, both of which inherit from A. If D calls a method defined in A, which path wins — D→B→A or D→C→A? Worse, if B and C both override the method, which override runs? Without a defined resolution order, the answer is ambiguous and depends on implementation.
C3 linearization produces an MRO that satisfies three properties: the class itself comes first; a class always appears before its parents; if multiple bases are specified, their relative order from the class definition is preserved. For the diamond D(B, C), D's MRO is [D, B, C, A, object]. You can inspect this at runtime with `ClassName.__mro__` or `ClassName.mro()`.
`super()` is the mechanism for traversing the MRO cooperatively. Crucially, `super()` does not mean 'call the parent class' — it means 'call the next class in the MRO of the original instance's class.' This distinction matters: when B calls `super().__init__()` inside `D.__init__()`, super() resolves to C (the next in D's MRO), not to A. If each class in the chain calls `super()`, all `__init__` methods run exactly once, in MRO order, without A being initialized twice.
This is cooperative multiple inheritance. It only works correctly when all classes in the hierarchy use `super()` consistently. Mixing `super()` calls with explicit parent calls (like `A.__init__(self)`) breaks the cooperation and can cause A to be called twice or skipped.
A practical implication: `super()` in Python 3 is zero-argument and uses `__class__` cell references — you no longer need to pass the class name explicitly as in Python 2. `super()` == `super(__class__, self)`.
When multiple inheritance is genuinely needed, mixins are the typical pattern: small, focused classes that add one capability and always use `super()`, designed to be composed into a target class without direct instantiation.
Correctly explains the diamond problem, describes C3 linearization at a conceptual level, and explains that super() follows MRO rather than just calling the immediate parent.
All of the above plus: walks through the concrete MRO for a diamond hierarchy, explains cooperative multiple inheritance (all classes must use super()), describes what breaks when they don't, and mentions the mixin pattern.
Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.
Get Graded — Free Assessment