super
Python
constructor
object-oriented programming
inheritance

How to invoke the super constructor in Python?

Object-Oriented Design practice on Codemia

Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.

Practice OOD

Introduction

In Python inheritance, child classes often need base-class initialization logic to run. The idiomatic way to call parent constructor behavior is super().__init__(...). Using super correctly is essential for maintainable class hierarchies, especially in multiple inheritance.

Basic Parent Constructor Call

Single inheritance example:

python
1class Animal:
2    def __init__(self, name):
3        self.name = name
4
5class Dog(Animal):
6    def __init__(self, name, breed):
7        super().__init__(name)
8        self.breed = breed
9
10pet = Dog("Milo", "Labrador")
11print(pet.name, pet.breed)

super() ensures base state is initialized before child-specific fields.

Why super() Instead of ParentClass Direct Call

Direct parent calls can work in simple trees, but they break composability in multiple inheritance. super() respects Python method resolution order and enables cooperative class design.

python
# less flexible pattern
# Animal.__init__(self, name)

Use direct parent calls only when you intentionally bypass cooperative inheritance.

Multiple Inheritance and MRO

super() becomes critical when multiple base classes participate.

python
1class A:
2    def __init__(self):
3        print("A")
4        super().__init__()
5
6class B:
7    def __init__(self):
8        print("B")
9        super().__init__()
10
11class C(A, B):
12    def __init__(self):
13        print("C")
14        super().__init__()
15
16C()
17print(C.__mro__)

Each class calls super(), and MRO ensures each initializer runs once in order.

Parameter Passing in Cooperative Hierarchies

In mixed base classes, use keyword arguments and forward leftovers.

python
1class Base:
2    def __init__(self, **kwargs):
3        super().__init__(**kwargs)
4
5class Timestamped(Base):
6    def __init__(self, created_at, **kwargs):
7        self.created_at = created_at
8        super().__init__(**kwargs)

This pattern avoids argument-collision issues in deep hierarchies.

Common Modern Syntax

In Python 3, always prefer zero-argument super() inside instance methods.

python
class Child(Parent):
    def __init__(self):
        super().__init__()

Old two-argument style remains valid but is rarely needed.

Debugging Constructor Chains

If initialization order looks wrong:

  • inspect Class.__mro__
  • verify each class calls super()
  • avoid mixing direct base calls and super in same hierarchy

Constructor bugs often come from one class skipping cooperative call.

super in Dataclass Inheritance

When combining dataclasses and inheritance, call parent initialization logic where needed to preserve base invariants.

python
1from dataclasses import dataclass
2
3@dataclass
4class Base:
5    name: str
6
7@dataclass
8class Child(Base):
9    age: int
10
11    def __post_init__(self):
12        super().__init__(self.name)

Careful design is needed because dataclass-generated constructors can interact with manual initialization paths.

Cooperative Method Design

In multiple inheritance, every participating class should call super() even if it does little work. This cooperative style keeps method resolution consistent and avoids skipped initialization in diamond-shaped hierarchies.

Debugging Tip

Log initializer entry points during development to confirm call order quickly:

python
print(ClassName.__mro__)

This often reveals why expected parent logic did not execute.

Real-World Example with Validation Base Class

Base classes often enforce validation or logging in __init__. Skipping super can silently bypass these safeguards. In production class hierarchies, this can cause inconsistent object state that is hard to diagnose later.

Testing Inheritance Initialization

Add tests that instantiate child classes and assert parent fields are initialized correctly. Constructor tests are lightweight and protect against regression when subclass code changes.

Refactoring Safety

When refactoring class hierarchies, re-check each constructor for cooperative super usage. Seemingly small initializer edits can break parent setup logic and create subtle downstream bugs in serialization, validation, or logging paths. A quick inheritance-focused test suite makes these regressions much easier to catch early.

Common Pitfalls

  • Forgetting to call super().__init__ in child constructors.
  • Mixing direct parent calls with cooperative super chains.
  • Ignoring MRO in multiple inheritance.
  • Passing positional arguments that clash across base classes.
  • Assuming super means only immediate parent in all contexts.

Summary

  • Use super().__init__ to invoke parent constructor logic in Python.
  • super is essential for cooperative multiple inheritance.
  • Prefer keyword-based forwarding for complex class graphs.
  • Inspect MRO when debugging initializer order.
  • Keep constructor design consistent across hierarchy.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Object-Oriented Design practice on Codemia

Turn requirements into classes, and defend the design, on the problems that come up in OOD rounds.

Practice OOD

All Rights Reserved.