Tutorial

Python super() - Python 3 super()

Practical guide to python super(): syntax, examples, Python 2 vs 3 differences, multilevel and multiple inheritance, MRO and best practices.

Drake Nguyen

Founder · System Architect

3 min read
Python super() - Python 3 super()
Python super() - Python 3 super()

What is python super() and why it matters

The python super() built-in provides a way for a subclass to delegate method calls to its superclass without hard-coding the base class name. This is useful in single inheritance, multilevel inheritance and cooperative multiple inheritance where using super() helps follow the class hierarchy and Python's method resolution order (MRO).

Basic example: replacing direct parent calls with super()

Compare calling a parent class constructor directly with using super().__init__ in Python 3. Both achieve the same result, but super() makes code easier to maintain when class names change or when inheritance becomes more complex.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print(f"{self.name}, {self.age}")

class Student(Person):
    def __init__(self, name, age, student_id):
        # direct parent call (works but is brittle)
        # Person.__init__(self, name, age)

        # preferred: python super()
        super().__init__(name, age)
        self.student_id = student_id

s = Student("Ava", 21, "S123")
s.show()

Notes on syntax

In Python 3 the most common form is super() or super().__init__(...). For legacy Python 2 code you will often see super(ClassName, self) which explicitly passes the current class and instance.

Python 2 vs python 3 super()

In Python 2, super requires two arguments: the subclass name and the instance (for example, super(Student, self)). Also, base classes should inherit from object to create new-style classes. If you forget this you can encounter the error "TypeError: must be type, not classobj" which reflects that the class is an old-style class in Python 2.

Multilevel inheritance and the immediate parent

super() follows Python's method resolution order (MRO). In multilevel inheritance super() routes calls to the next class in the MRO, which typically acts like the immediate parent but is actually determined by the computed linearization. This is what enables predictable initialization order across a class chain.

Cooperative multiple inheritance and MRO

When multiple inheritance is present, super() is essential for cooperative behavior: each class calls super() so the next class in the MRO can also run its initializer or method. This avoids duplicated work and makes constructors and methods compose correctly.

class A:
    def __init__(self):
        print("A.__init__")

class B(A):
    def __init__(self):
        print("B.__init__ start")
        super().__init__()
        print("B.__init__ end")

class C(A):
    def __init__(self):
        print("C.__init__ start")
        super().__init__()
        print("C.__init__ end")

class D(B, C):
    def __init__(self):
        print("D.__init__ start")
        super().__init__()  # this follows D.__mro__ to call B, C, then A
        print("D.__init__ end")

# Demonstrates cooperative multiple inheritance using python super()
d = D()

Why this matters

  • Using super avoids hard-coded parent class names and helps prevent errors when refactoring.
  • It enables cooperative multiple inheritance — each class gets a chance to participate.
  • super() works for more than just __init__; you can call any parent method through it.

When to use super() vs direct parent class call

Prefer super() in modern Python (Python 3) especially when your classes may be extended or combined with multiple inheritance. Directly calling the parent class (e.g., ParentClass.method(self, ...)) can be acceptable for simple, single-inheritance cases, but it bypasses the MRO and can break cooperative behavior in complex hierarchies.

Common pitfalls and tips

  • In Python 2, remember to inherit from object to avoid "must be type not classobj" errors when using super.
  • Always design __init__ signatures to accept and forward parameters when cooperating across multiple classes.
  • Use tools like class.__mro__ or inspect.getmro() to inspect the method resolution order when debugging super() behavior.

Further reading and best practices

For reliable, maintainable code: favor the Python 3 super() syntax, design constructors for cooperative inheritance, and rely on MRO-aware calls rather than hard-coded base class invocations. Consult the official Python documentation on super() and MRO for deeper details about resolution order and cooperative multiple inheritance.

Stay updated with Netalith

Get coding resources, product updates, and special offers directly in your inbox.