Rozdział 14 · Tworzenie rzeczywistych obiektów

super() i procedura rozwiązywania rozwiązań

super() pozwala klasie podrzędnej korzystać z metody rodzica z samego nadpisywania — zamiast przepisywać ją od nowa.

super(): dzwonić do rodzica, a nie go zastępować

super() daje dostęp do metod klasy nadrzędnej OD WEWNĄTRZ metoda nadpisana — zwykle po to, by UZUPEŁNIĆ zachowanie rodzica, a nie je zastąpić Całkowicie:

super_init.py
class Zhivotnoe:
    def __init__(self, klichka):
        self.klichka = klichka


class Sobaka(Zhivotnoe):
    def __init__(self, klichka, poroda):
        super().__init__(klichka)   # wykonuje Zhivotnoe.__init__(self klichka)
        self.poroda = poroda         # następnie dodaje swoje

rex = Sobaka(„Rex”, „Kundel”)
print(rex.klichka, rex.poroda)   # Rex Mongrel – Oba atrybuty są obecne
Powszechne nieporozumienie: „super() zwraca obiekt klasy nadrzędnej”
To nieprawda. super() zwraca specjalny pośredni obiekt (proxy), który potrafi znajdować metody RODZICA dla BIEŻĄCEGO selfself pozostaje obiektem Sobakanie zamienia się w Zhivotnoe. Po prostu tym razem poszukiwanie metody się nie zaczyna Sobaka, ale o poziom wyżej.

Kolejność rozwiązywania metod (MRO)

W przypadku normalnego pojedynczego dziedziczenia procedura znalezienia metody jest prosta i przewidywalna: najpierw klasa obiektu, potem jej rodzic, potem rodzic rodzica — i tak dalej object, podstawowa klasa dla wszystkich klas w Python:

Sobakapierwszy tutajZhivotnoenastępnie tutajobjecti na samym końcu
MRO dla pojedynczego dziedziczenia – przewidywalna kolejność wyszukiwania
Debug Lab 9: Użyj atrybutu BEFORE, aby wywołać super().__init__()
nepravilnyj_poryadok.py
class Sobaka(Zhivotnoe):
    def __init__(self, klichka, poroda):
        self.poroda = poroda
        print(f"Rasa: {self.poroda}, przezwyk: {self.klichka}")   # klichka jeszcze nie!
        super().__init__(klichka)
Traceback (most recent call last):
    print(f"Порода: {self.poroda}, кличка: {self.klichka}")
AttributeError: 'Sobaka' object has no attribute 'klichka'
Co widać na ekranie

super().__init__(klichka) powinno być PO ZA linijką, która już próbuje przeczytać self.klichka jest już rodzicem __init__ jeszcze nie wykonano, atrybut jeszcze nie utworzono. Kolejność wywołań wewnątrz __init__ wykonywana jest ściśle od góry do dołu, jak w każdej innej funkcji.

Poprawiony kod
pravilnyj_poryadok.py
class Sobaka(Zhivotnoe):
    def __init__(self, klichka, poroda):
        super().__init__(klichka)   # Rodzic na pierwszym miejscu
        self.poroda = poroda
        print(f"Rasa: {self.poroda}, przezwyk: {self.klichka}")
Praktyka: super()
interaktywny laptop bezpośrednio w przeglądarce – Python 3.14 przez Pyodide, bez instalacji
Otwórz praktykę →