super()
Wywołuje metodę klasy bazowej z wnętrza klasy pochodnej, najczęściej konstruktor __init__.
- Zwraca
- Obiekt pośredniczący, przez który wywołujesz metody następnej klasy w kolejności MRO, zwykle klasy bazowej.
Przykład
#class User:
def __init__(self, name):
self.name = name
self.active = True
class Student(User):
def __init__(self, name, world):
super().__init__(name)
self.world = world
self.points = 0
ola = Student("Ola", 7)
print(ola.name, ola.active)
print(ola.world, ola.points)Definicja i zastosowanie
#Funkcja super() zwraca obiekt pośredniczący, przez który wywołasz metodę z klasy bazowej. Najczęściej używa się jej w __init__ klasy pochodnej: super().__init__(name) pozwala klasie bazowej ustawić swoje atrybuty, a klasa pochodna dopisuje tylko nowe.
Tak samo rozszerza się każdą nadpisaną metodę. Zamiast kopiować kod z klasy bazowej, wywołujesz super().metoda() i dokładasz coś przed albo po. Jeśli tego nie zrobisz, wersja bazowa w ogóle się nie wykona. W przypadku __init__ oznacza to brak atrybutów, które ustawia klasa bazowa.
Wewnątrz metody wystarczy napisać super() bez argumentów, bo Python sam ustali klasę i obiekt. Przy dziedziczeniu wielokrotnym super() nie wskazuje po prostu „rodzica”, tylko następną klasę w kolejności MRO obiektu. Dzięki temu każda klasa w hierarchii wykona się dokładnie raz, pod warunkiem że wszystkie konsekwentnie wywołują super().
Składnia
#class Pochodna(Bazowa):
def __init__(self, a, b):
super().__init__(a)
self.b = b
def metoda(self):
wynik = super().metoda()
...Parametry
#type
klasa, opcjonalna
Klasa, za którą zaczyna się wyszukiwanie metody w kolejności MRO. Wewnątrz metod pomijana.object_or_type
obiekt lub klasa, opcjonalny
Obiekt, dla którego wywołujesz metodę. Wewnątrz metod pomijany.
Więcej przykładów
#class Reward:
def __init__(self, exp):
self.exp = exp
def describe(self):
return f"+{self.exp} EXP"
class StreakReward(Reward):
def __init__(self, exp, days):
super().__init__(exp)
self.days = days
def describe(self):
return super().describe() + f" i seria {self.days} dni"
print(Reward(10).describe())
print(StreakReward(15, 7).describe())class User:
def __init__(self, name):
self.name = name
class Mentor(User):
def __init__(self, name, course):
self.course = course
darwin = Mentor("Darwin", "Python")
print(darwin.course)
print(hasattr(darwin, "name"))class Lesson:
def start(self):
print("Lesson: ładuję treść")
class WithTimer(Lesson):
def start(self):
print("WithTimer: włączam stoper")
super().start()
class WithHints(Lesson):
def start(self):
print("WithHints: przygotowuję podpowiedzi")
super().start()
class Quiz(WithTimer, WithHints):
def start(self):
print("Quiz: start")
super().start()
Quiz().start()super() w klasie WithTimer wywołuje metodę z WithHints, a nie z Lesson, bo tak wygląda kolejność MRO obiektu Quiz. Dzięki temu Lesson.start() wykonuje się tylko raz.
Dobre praktyki
#- W
__init__klasy pochodnej wywołujsuper().__init__(...)na początku, zanim skorzystasz z atrybutów ustawianych przez klasę bazową. - Nie wpisuj nazwy klasy bazowej na sztywno, np.
User.__init__(self, name).super()działa poprawnie także po zmianie hierarchii i przy dziedziczeniu wielokrotnym. - Przy dziedziczeniu wielokrotnym każda klasa w łańcuchu powinna wywoływać
super(). Jedna klasa bez tego wywołania przerywa cały łańcuch.
Powiązane hasła
#- DziedziczenieBudowanie klasy na bazie innej: klasa pochodna przejmuje metody klasy bazowej i może je rozszerzać lub nadpisywać.
- __init__()Metoda wywoływana automatycznie przy tworzeniu obiektu. Zapisuje w nim dane początkowe, czyli atrybuty.
- classDefiniuje klasę: szablon obiektów łączący dane i funkcje, które na nich działają.
- *args i **kwargsZbieranie dowolnej liczby argumentów pozycyjnych w krotkę i nazwanych w słownik oraz rozpakowywanie kolekcji przy wywołaniu.
Widzisz błąd albo brakuje przykładu? Napisz do nas.