super()

Cooperative multiple inheritance — call the parent's method without hard-coding the class name.

Built-in function / typePython 2.2+Live demo
Common call
super().__init__(...)
Returns
a proxy — calls dispatch to the next class in the MRO
Replaces
`ParentClass.method(self, ...)` — but does not hard-code the parent name
Watch out
the zero-arg form only works INSIDE a method; outside you need the two-arg form
super() / super(type, obj_or_typeobj_or_typeThe instance (or class) whose MRO to walk. The zero-arg form uses the first positional argument of the enclosing method.type: Any · default: self)
super

Demo

Live evaluation
Try:
Inputs
scenariostrscenario: init / single / diamond
Output
super('init')
'class Person:\n def __init__(self, name):\n self.name = name\n\nclass Employee(Person):\n def __init__(self, name, salary):\n super().__init__(name) # calls Person.__init__\n self.salary = salary\n\n# Employee("Alice", 50000)\n# → runs Person.__init__ (self.name = "Alice"), then sets self.salary'

super() is a proxy for the NEXT class in the MRO (method resolution order). The demo shows three common scenarios. INIT: subclass __init__ calls super().__init__() to run parent initialization. SINGLE: an override calls super().method() to extend the parent's behavior. DIAMOND: with multiple inheritance, super() follows the linearized MRO — critical for cooperative multiple inheritance.

Parameters

NameTypeRequiredDescription
typetypeno (__class__)The starting class for MRO lookup. In the zero-arg form (Python 3.0+), the compiler fills this in as the class the method is defined in.
obj_or_typeAnyno (self)The instance (or class) whose MRO to walk. The zero-arg form uses the first positional argument of the enclosing method.

Return value

superA proxy object. Calling methods on it dispatches to the parent (next-in-MRO) class, bound to the current instance or class. `super()` inside a method (Python 3.0+) is equivalent to `super(__class__, self)` — the compiler fills in the arguments.

Common patterns

Extend __init__ in a subclass
The most common super() use — run the parent's initializer.
class Employee(Person):
    def __init__(self, name, salary):
        super().__init__(name)
        self.salary = salary
Extend a method
Call the parent method, then add subclass behavior.
class Loud(Talker):
    def speak(self):
        text = super().speak()
        return text.upper()
Cooperative multiple inheritance
Every class in the hierarchy calls super() — the MRO walks through each once.
class A:
    def do(self): print("A"); 
class B(A):
    def do(self): print("B"); super().do()
class C(A):
    def do(self): print("C"); super().do()
class D(B, C):
    def do(self): print("D"); super().do()
Two-arg form outside a method
When you need super() at module level or in a static context.
super(Employee, e).__init__(name)

Examples

1. Init
class Sub(Base): def __init__(self, x): super().__init__() self.x = x
Returns
runs Base.__init__
2. Method extension
class Loud(Talker): def speak(self): return super().speak().upper()
Returns
upcase result
3. MRO walk
D.__mro__
Returns
(D, B, C, A, object)
4. Zero-arg inside method
super().method()
Returns
next in MRO
5. Two-arg outside method
super(D, d).method()
Returns
explicit start class

Pitfalls

1. Zero-arg super() only works INSIDE a method
The zero-arg form is compiler magic — it reads __class__ from the enclosing method definition. At module level or in a static function, it raises RuntimeError.
Outside method fails
# at module level
super()
RuntimeError: super(): no arguments
Two-arg form
super(SomeClass, instance)
works anywhere
2. super() does NOT mean "parent class" — it means "next in MRO"
A single-inheritance mental model breaks with multiple inheritance. With diamond inheritance, super() may dispatch to a SIBLING class, not the "parent" you had in mind.
Assumed parent
# in D(B, C):
# super() in B goes to A, right?
no — goes to C, then A
Read the MRO
D.__mro__
(D, B, C, A, object)
3. Must be a cooperative hierarchy — every class calls super()
If one class in the chain forgets to call super(), the MRO walk stops there. This is subtle in multi-inheritance code; the common convention is "every class calls super() for methods it might share".
One class breaks chain
class B(A):
    def do(self):
        print("B")   # no super() — stops here
A.do never runs
Always call super()
class B(A):
    def do(self):
        print("B")
        super().do()
A.do runs after B
4. super() vs Parent.method(self) — subtly different
The hard-coded form works only for single inheritance. As soon as multiple inheritance appears, super() respects the MRO but the hard-coded form does not — leading to skipped classes or double-run methods.
Hard-coded skips MRO
class D(B, C):
    def do(self):
        B.do(self)   # C.do never runs
diamond broken
super() follows MRO
class D(B, C):
    def do(self):
        super().do()
B and C both invoked

When to use

Use it
  • Every __init__ in a subclass — the standard convention
  • Extending any inherited method rather than replacing it
  • Cooperative multiple inheritance and mixins
  • When a subclass wants to add behavior around a parent method
Reach for something else
  • Complete replacement of a parent method — do not call super()
  • Naming ambiguity — if the parent method is unclear, refactor
  • Deep hierarchies — often a sign that composition would be clearer
  • When you truly want a specific class's method regardless of MRO — use ParentClass.method(self)

Notes

Complexity
O(1) proxy creation; O(mro depth) attribute lookup
Return
A super proxy — bound to the current instance
CPython impl
Objects/typeobject.c :: super_new
Memory
Small proxy object
Thread-safe
Yes for immutable class hierarchies

FAQ

If the parent has meaningful __init__ behavior, yes — otherwise inherited attributes will not initialize. The one exception: if you inherit directly from object and have no other cooperative parents, super().__init__() with no args is a no-op but still recommended for consistency.

History

2.2
super() introduced with new-style classes.
3.0
Zero-arg super() enabled by the compiler filling in __class__ and self.