Глава 14 · Создаём объекты реального мира

super() и порядок разрешения методов

super() позволяет дочернему классу воспользоваться методом родителя изнутри переопределения — а не заново писать его с нуля.

super(): позвать родителя, а не заменить его

super() даёт доступ к методам родительского класса ИЗНУТРИ переопределённого метода — обычно чтобы ДОПОЛНИТЬ поведение родителя, а не заменить его целиком:

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


class Sobaka(Zhivotnoe):
    def __init__(self, klichka, poroda):
        super().__init__(klichka)   # выполняет Zhivotnoe.__init__(self, klichka)
        self.poroda = poroda         # затем добавляет своё

rex = Sobaka("Рекс", "Дворняга")
print(rex.klichka, rex.poroda)   # Рекс Дворняга — оба атрибута на месте
Частое заблуждение: «super() возвращает объект родительского класса»
Это не так. super() возвращает специальный промежуточный объект (прокси), который умеет находить методы РОДИТЕЛЯ для ТЕКУЩЕГО selfself остаётся объектом класса Sobaka, он не превращается в Zhivotnoe. Просто поиск метода на этот раз начинается не с Sobaka, а на уровень выше.

Порядок разрешения методов (MRO)

При обычном одиночном наследовании порядок поиска метода простой и предсказуемый: сначала сам класс объекта, затем его родитель, затем родитель родителя — и так до object, базового класса для всех классов в Python:

Sobakaсначала здесьZhivotnoeзатем здесьobjectи в самом конце
MRO для одиночного наследования — предсказуемый порядок поиска
Debug Lab 9: используют атрибут ДО вызова super().__init__()
nepravilnyj_poryadok.py
class Sobaka(Zhivotnoe):
    def __init__(self, klichka, poroda):
        self.poroda = poroda
        print(f"Порода: {self.poroda}, кличка: {self.klichka}")   # klichka ещё нет!
        super().__init__(klichka)
Traceback (most recent call last):
    print(f"Порода: {self.poroda}, кличка: {self.klichka}")
AttributeError: 'Sobaka' object has no attribute 'klichka'
Что видно на экране

super().__init__(klichka) стоит ПОСЛЕ строки, которая уже пытается прочитать self.klichka — на этот момент родительский __init__ ещё не выполнялся, атрибут ещё не создан. Порядок вызовов внутри __init__ исполняется строго сверху вниз, как и в любой другой функции.

Исправленный код
pravilnyj_poryadok.py
class Sobaka(Zhivotnoe):
    def __init__(self, klichka, poroda):
        super().__init__(klichka)   # сначала родительская часть
        self.poroda = poroda
        print(f"Порода: {self.poroda}, кличка: {self.klichka}")
Практика: super()
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки
Открыть практику →