W Pythonie wspierane jest dziedziczenie wielokrotne, a wywołania metod rodziców są zarządzane za pomocą liniowej sekwencji rozwiązywania metod (MRO — Method Resolution Order). Funkcja super() pozwala na wywołanie metody superklasy w hierarchii i jest szczególnie przydatna w przypadku skomplikowanego dziedziczenia.
super() gwarantuje poprawne wywołanie metod zgodnie z MRO, a nie tylko u bezpośredniego rodzica.
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() D().do() # Wyświetli: # D # B # C # A
Szczegóły: Każda metoda musi wywołać super(), w przeciwnym razie MRO "złamię" się. Również konstruktory (__init__) muszą wywołać super().__init__().
Pytanie: Co się stanie, jeśli w hierarchii dziedziczenia wielokrotnego jedna z klas "zapomni" wywołać super() w swojej metodzie?
Odpowiedź: MRO zostanie naruszone, część metod rodziców po prostu nie zostanie wywołana. Przykład:
class A: def show(self): print('A') class B(A): def show(self): print('B') class C(A): def show(self): print('C') super().show() class D(B, C): def show(self): print('D'); super().show() D().show() # Wyświetli: D B # Metody A i C nie są w ogóle wywoływane
Historia
super().__init__() w jednej z klas pośrednich. W wyniku tego jeden z widżetów nie został poprawnie zainicjowany, a wskazywał na to jedynie rzadki błąd.Historia
Historia
W skomplikowanej hierarchii mixinów podczas nadpisywania jeden z metod "zapomniał" wywołać super(). Doprowadziło to do tego, że z jednego punktu końcowego API walidacja nie działała, a z innego — działała poprawnie. Błąd znaleziono po tygodniach, analizując MRO ręcznie.