Die Python-Funktion super() liefert ein Proxy-Objekt, über das Methoden der Oberklasse aufgerufen werden können — am häufigsten beim Erweitern von __init__ in einer Subklasse. Anders als der direkte Aufruf Parent.method(self, ...) respektiert super() die Method Resolution Order (MRO) und ist damit die einzig richtige Wahl bei Mehrfachvererbung.
Einleitung
Wer in einer Subklasse __init__ überschreibt, möchte oft die Initialisierung der Oberklasse trotzdem ausführen. Direkt mit Parent.__init__(self, ...) wäre möglich, ist aber spröde:
- Bei Umbenennen der Oberklasse müssen alle Aufrufe nachgezogen werden.
- Bei Mehrfachvererbung wird die MRO ignoriert — Diamond-Problem-Fehler vorprogrammiert.
super().__init__(...) löst beide Probleme. Es findet die nächste Klasse in der MRO und ruft deren Methode auf — mit self automatisch eingesetzt.
Seit Python 3 reicht der parameterlose Aufruf super() — innerhalb einer Methode weiß Python automatisch, in welcher Klasse er steht. Die explizite Form super(ChildClass, self) ist nur in seltenen dynamischen Szenarien nötig.
Syntax
super() # Python 3, innerhalb von Methoden
super(SubClass, instance) # explizite FormSubClass (Optional) Klasse, ab der die MRO durchlaufen wird.
instance (Optional) Instanz, an die self gebunden wird.
Rückgabewert
Ein Proxy-Objekt, über das Methoden der Oberklasse(n) entlang der MRO aufgerufen werden.
Beispiele
Standard-Erweiterung von init
Der Klassiker — die Subklasse erweitert die Initialisierung der Oberklasse, statt sie zu duplizieren:
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
d = Dog("Rex", "Beagle")
print(d.name, d.breed)Rex BeagleMethode überschreiben und Original aufrufen
super() ist auch für reguläre Methoden nützlich — z. B. um die Original-Logik zu erweitern statt zu ersetzen:
class Logger:
def log(self, msg):
print(f"[LOG] {msg}")
class TimestampedLogger(Logger):
def log(self, msg):
from datetime import datetime
super().log(f"{datetime.now().time()} — {msg}")
TimestampedLogger().log("Starting")[LOG] 10:00:00.000000 — StartingMRO bei Mehrfachvererbung
Bei Mehrfachvererbung folgt super() der MRO (C3-Linearisierung) — sichtbar über cls.__mro__:
class A:
def hello(self): print("A")
class B(A):
def hello(self): print("B"); super().hello()
class C(A):
def hello(self): print("C"); super().hello()
class D(B, C):
def hello(self): print("D"); super().hello()
D().hello()
print([cls.__name__ for cls in D.__mro__])D
B
C
A
['D', 'B', 'C', 'A', 'object']Praktische Beispiele
Mixin-Klasse für Validierung
Mixins fügen Funktionalität via Vererbung hinzu — super() macht sie kooperativ:
class ValidatedMixin:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.validate()
def validate(self):
if not self.name:
raise ValueError("name darf nicht leer sein")
class User(ValidatedMixin):
def __init__(self, name):
self.name = name
super().__init__()
try:
User("")
except ValueError as e:
print(e)
u = User("Michael")
print(u.name)name darf nicht leer sein
MichaelDecorated Klasse mit erweiterter repr
super().__repr__() liefert die Default-Repräsentation — perfekt als Basis für Erweiterungen:
class Trackable:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._created_at = "2026-05-03"
def __repr__(self):
return f"<{super().__repr__()} created={self._created_at}>"
class Item(Trackable):
def __init__(self, name):
super().__init__()
self.name = name
print(repr(Item("widget")))<<__main__.Item object at 0x...> created=2026-05-03>*args, **kwargs für Cooperative Multiple Inheritance
In Mixin-Hierarchien ist es Standard, *args, **kwargs an super().__init__() weiterzugeben — so bleiben alle Klassen der MRO interoperabel:
class Loggable:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
print(f"created {type(self).__name__}")
class Item(Loggable):
def __init__(self, name):
super().__init__()
self.name = name
Item("widget")created ItemPraktische Hinweise
- In Python 3 immer
super()ohne Argumente — die explizite Form nur in dynamisch generiertem Code. - MRO sehen:
cls.__mro__odercls.mro()zeigt die Auflösungsreihenfolge. - Cooperative Multiple Inheritance funktioniert nur, wenn ALLE Klassen
super()korrekt aufrufen und*args, **kwargsdurchreichen. objectschluckt überflüssige__init__-Argumente nicht — bei kooperativen Hierarchien ggf. eine eigene Basisklasse einführen.- Verwandte API:
cls.__bases__(direkte Eltern),inspect.getmro(cls),isinstance()/issubclass().