Наследование полезно, но вы можете полностью раскрыть его потенциал, повторно используя код базовых классов.
Ключевые выводы
- Функция Python super() позволяет вызывать методы суперкласса из подкласса, что упрощает реализацию наследования и переопределения методов.
- Функция super() тесно связана с порядком разрешения методов (MRO) в Python, который определяет порядок, в котором классы-предки ищут методы или атрибуты.
- Использование super() в конструкторах классов — обычная практика для инициализации общих атрибутов в родительском классе и более конкретных атрибутов в дочернем классе. Неиспользование super() может привести к непредвиденным последствиям, например к отсутствию инициализации атрибутов.
Одной из основных особенностей Python является парадигма ООП, которую можно использовать для моделирования объектов реального мира и их отношений.
При работе с классами Python вы часто будете использовать наследование и переопределять атрибуты или методы суперкласса. Python предоставляет супер() функция, которая позволяет вызывать методы суперкласса из подкласса.
Что такое super() и зачем он вам нужен?
Используя наследование, вы можете создать новый класс Python, который наследует функции существующего класса. Вы также можете переопределить методы суперкласса в подклассе, предоставляя альтернативные реализации. Однако вы можете захотеть использовать новую функциональность в дополнение к старой, а не вместо нее. В этом случае, супер() Полезно.
Вы можете использовать супер() функция для доступа к атрибутам суперкласса и вызова методов суперкласса. Супер необходим для объектно-ориентированного программирования потому что это упрощает реализацию наследования и переопределения методов.
Как работает super()?
Внутренне, супер() тесно связан с Порядок разрешения метода (MRO) в Python, который определяет алгоритм линеаризации C3.
Вот как супер() работает:
- Определить текущий класс и экземпляр: Когда ты звонишь супер() внутри метода подкласса Python автоматически определяет текущий класс (класс, содержащий метод, вызвавший супер()) и экземпляр этого класса (т.е. себя).
- Определить суперкласс: супер() принимает два аргумента — текущий класс и экземпляр, — которые вам не нужно передавать явно. Он использует эту информацию для определения суперкласса, которому делегируется вызов метода. Это делается путем изучения иерархии классов и MRO.
- Вызов метода суперкласса: Как только суперкласс определен, супер() позволяет вам вызывать его методы, как если бы вы вызывали их непосредственно из подкласса. Это позволяет вам расширять или переопределять методы, сохраняя при этом исходную реализацию суперкласса.
Использование super() в конструкторе класса
С использованием супер() в конструкторе класса — это обычная практика, поскольку часто требуется инициализировать общие атрибуты в родительском классе, а более конкретные — в дочернем.
Чтобы продемонстрировать это, определить класс Python, Отец, который Сын класс наследуется от:
classFather:
def__init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_nameclassSon(Father):
def__init__(self, first_name, last_name, age, hobby):
# Call the parent class constructor (Father)
super().__init__(first_name, last_name)self.age = age
self.hobby = hobbydefget_info(self):
returnf"Son's Name: {self.first_name}{self.last_name}, \
Son's Age: {self.age}, Son's Hobby: {self.hobby}"# Create an instance of the Son class
son = Son("Pius", "Effiong", 25, "Playing Guitar")
# Access attributes
print(son.get_info())
Внутри Сын конструктор, вызов супер().инит() призывает Отец конструктор класса, передавая его имя и фамилия в качестве параметров. Это гарантирует, что Отец класс по-прежнему может правильно устанавливать атрибуты имени даже на Сын объект.
Если вы не позвоните супер() в конструкторе класса конструктор его родительского класса не запускается. Это может привести к непредвиденным последствиям, таким как отсутствие инициализации атрибутов или неполная настройка состояния родительского класса:
...
classSon(Father):
def__init__(self, first_name, last_name, age, hobby):
self.age = age
self.hobby = hobby
...
Если вы сейчас попытаетесь вызвать получить данные метод, это повысит Ошибка атрибута поскольку self.first_name и self.last_name атрибуты не были инициализированы.
Использование super() в методах класса
Вы можете использовать супер() в других методах, кроме конструкторов, точно так же. Это позволяет вам расширить или переопределить поведение метода суперкласса.
classFather:
defspeak(self):
return"Hello from Father"classSon(Father):
defspeak(self):
# Call the parent class's speak method using super()
parent_greeting = super().speak()
returnf"Hello from Son\n{parent_greeting}"# Create an instance of the Son class
son = Son()# Call the speak method of the Son class
son_greeting = son.speak()
print(son_greeting)
Сын класс наследует от Отец и имеет свое говорить метод. говорить метод Сын класс использует супер().говорить() позвонить в говорить метод Отец сорт. Это позволяет ему включать сообщение из родительского класса, расширяя его сообщением, специфичным для дочернего класса.
Не удалось использовать супер() в методе, который переопределяет другой, означает, что функциональность, присутствующая в методе родительского класса, не вступит в силу. Это приводит к полной замене поведения метода, что может привести к нежелательному поведению.
Понимание порядка разрешения метода
Порядок разрешения метода (MRO) — это порядок, в котором Python ищет классы-предки при доступе к методу или атрибуту. MRO помогает Python определить, какой метод вызывать, если существует несколько иерархий наследования.
classNigeria():
defculture(self):
print("Nigeria's culture")
classAfrica():
defculture(self):
print("Africa's culture")
Вот что происходит, когда вы создаете экземпляр Лагос класс и позвони культура метод:
- Python начинает с поиска культура метод в Лагос сам класс. Если он его находит, он вызывает метод. Если нет, он переходит ко второму шагу.
- Если он не находит культура метод в Лагос class, Python просматривает базовые классы в том порядке, в котором они указаны в определении класса. В этом случае, Лагос наследует сначала от Африка а потом из Нигерия. Итак, Python будет искать культура метод в Африка первый.
- Если он не находит культура метод в Африка класс, Python затем просмотрит Нигерия сорт. Такое поведение продолжается до тех пор, пока не достигнет конца иерархии и не выдаст ошибку, если не удастся найти метод ни в одном из суперклассов.
В выводе показан порядок разрешения метода. Лагос, начиная слева направо.
Распространенные ошибки и лучшие практики
При работе с супер(), есть некоторые распространенные ошибки, которых следует избегать.
- Помните о порядке разрешения методов, особенно в сценариях множественного наследования. Если вам нужно использовать сложное множественное наследование, вы должны быть знакомы с Алгоритм линеаризации C3 который Python использует для определения MRO.
- Избегайте циклических зависимостей в иерархии классов, которые могут привести к непредсказуемому поведению.
- Четко документируйте свой код, особенно при использовании супер() в сложных иерархиях классов, чтобы сделать его более понятным для других разработчиков.
Используйте super() правильно
Python супер() Функция — это мощная функция, когда вы работаете с наследованием и переопределением методов. Понимание того, как супер() работает, и следование лучшим практикам позволит вам создавать более удобный и эффективный код в ваших проектах Python.