ProgrammingSenior Python Developer

What is multiple inheritance in Python, what are the historical reasons for its emergence, and how does Python resolve method resolution order conflicts?

Pass interviews with Hintsage AI assistant

Answer

History

Multiple inheritance — the ability of a class to inherit from multiple parent classes — appeared in Python inspired by other OOP languages (for example, C++), where it helps to create reusable mixins. The development of the method resolution order (MRO) mechanism took a lot of time to ensure predictability in method conflicts.

Problem

A class may receive methods with the same name from different base classes. How to determine which method to use when called? Without a clear scheme, this leads to subtle bugs.

Solution

Python implements the MRO algorithm (C3 linearization), which defines a strict order of method searching when resolving conflicts in a hierarchy. Everything becomes transparent when using the super() function and the __mro__ method of classes to analyze the inheritance chain.

Example code:

class A: def foo(self): print("A") class B(A): def foo(self): print("B") super().foo() class C(A): def foo(self): print("C") super().foo() class D(B, C): def foo(self): print("D") super().foo() D().foo() print(D.__mro__)

Key features:

  • Python applies C3 linearization to build the method resolution order (MRO);
  • super() allows access to the next class in the MRO chain instead of one specific parent;
  • the MRO order can be viewed through the class attribute __mro__;

Trick Questions.

What happens if parent method names collide?

Answer: The method call will occur in the order defined by the MRO. The first found method with the required name in the chain will be the one that executes.

Can you use super() without explicitly passing self?

Answer: In Python 3 — yes, the call super().method() in the body of a class method is equivalent to the explicit super(Class, self).method(), but only inside the class.

Can the MRO order of an existing class be changed?

Answer: The MRO order is static after the class declaration, but it can be inspected (or a new class can be built with a different inheritance order).

Common Mistakes and Anti-Patterns

  • Forgetting to call super(), which can break the "chain" and skip initialization;
  • Using direct calls to parent methods (e.g., Parent.method(self)), which breaks the MRO;
  • Creating a complex hierarchy with conflicting order, which will lead to an MRO error (TypeError: Cannot create a consistent method resolution order (MRO));

Real-life Example

Negative Case

In the project, two mixins with similar methods were created, and the inheriting class uses both mixins but calls methods directly by class name, breaking the sequence of events.

Advantages:

  • Clear where the method is called from.

Disadvantages:

  • MRO breaks, not all methods are called, bugs where base classes meet.

Positive Case

Using super() in every method of the mixins ensures calls follow the chain, rather than skipping necessary behavior.

Advantages:

  • Predictable execution, easy to change class structure.
  • Good maintainability, new mixins can be easily integrated.

Disadvantages:

  • Requires discipline and understanding of the principles of super() and MRO.