pvdocs /Python/Multiple Inheritance

Multiple Inheritance

Python supports inheriting from more than one base class.

Basic Syntax

class A:
    def hello(self):
        print("Hello from A")

class B:
    def hello(self):
        print("Hello from B")

class C(A, B):  # inherits from both A and B
    pass

c = C()
c.hello()  # "Hello from A" — A comes first in MRO

MRO — Method Resolution Order

Python uses the C3 linearization algorithm to determine the order in which base classes are searched.

C.__mro__
# (<class 'C'>, <class 'A'>, <class 'B'>, <class 'object'>)

# Inspect at runtime
C.mro()

Rule of thumb: left-to-right, depth-first, no class appears before its subclass.

The Diamond Problem

class Base:
    def method(self):
        print("Base")

class Left(Base):
    def method(self):
        print("Left")

class Right(Base):
    def method(self):
        print("Right")

class Diamond(Left, Right):
    pass

Diamond().method()  # "Left"
Diamond.__mro__
# Diamond → Left → Right → Base → object

C3 linearization ensures Base appears only once.

super() and MRO

super() follows the MRO, not just the immediate parent. This is crucial in multiple inheritance.

class Base:
    def method(self):
        print("Base")

class Left(Base):
    def method(self):
        print("Left")
        super().method()   # calls Right.method (next in MRO)

class Right(Base):
    def method(self):
        print("Right")
        super().method()   # calls Base.method

class Diamond(Left, Right):
    def method(self):
        print("Diamond")
        super().method()

Diamond().method()
# Diamond → Left → Right → Base

Mixins Pattern

A mixin is a class designed to add a specific, reusable behavior without being instantiated directly.

class JsonMixin:
    def to_json(self):
        import json
        return json.dumps(self.__dict__)

class LogMixin:
    def log(self):
        print(f"[LOG] {self.__class__.__name__}: {self.__dict__}")

class User(JsonMixin, LogMixin):
    def __init__(self, name, email):
        self.name  = name
        self.email = email

u = User("Alice", "alice@example.com")
u.to_json()  # '{"name": "Alice", "email": "alice@example.com"}'
u.log()

Key Interview Points