Наследяването е полезно, но можете да отключите пълния му потенциал, като използвате повторно код от базови класове.

Ключови изводи

  • Функцията super() на Python ви позволява да извиквате методи на суперклас от подклас, което улеснява прилагането на наследяване и заместване на метод.
  • Функцията super() е тясно свързана с реда за разрешаване на метода (MRO) в Python, който определя реда, в който предшестващите класове се търсят за методи или атрибути.
  • Използването на super() в конструкторите на класове е обичайна практика за инициализиране на общи атрибути в родителския клас и по-специфични в дъщерния клас. Неуспешното използване на super() може да доведе до нежелани последствия, като например липсващи инициализации на атрибути.

Една от основните характеристики на Python е неговата OOP парадигма, която можете да използвате за моделиране на обекти от реалния свят и техните взаимоотношения.

Когато работите с класове на Python, често ще използвате наследяване и ще замените атрибутите или методите на суперклас. Python предоставя a

instagram viewer
супер() функция, която ви позволява да извиквате методите на суперкласа от подкласа.

Какво е super() и защо ви е необходимо?

Използвайки наследяване, можете да създадете нов клас Python, който наследява характеристиките на съществуващ клас. Можете също така да замените методите на суперкласа в подкласа, предоставяйки алтернативни реализации. Въпреки това може да искате да използвате новата функционалност в допълнение към старата, а не вместо нея. В такъв случай, супер() е полезно.

Можете да използвате супер() функция за достъп до атрибути на суперклас и извикване на методи на суперкласа. Супер е от съществено значение за обектно-ориентирано програмиране защото улеснява прилагането на наследяване и замяна на метод.

Как работи super()?

вътрешно, супер() е тясно свързано с Ред за разрешаване на метода (MRO) в Python, което определя алгоритъмът за линеаризация C3.

Ето как супер() върши работа:

  1. Определете текущия клас и екземпляр: Когато се обадите супер() вътре в метод на подклас, Python автоматично намира текущия клас (класът, съдържащ метода, който е извикал супер()) и екземпляра на този клас (т.е. себе си).
  2. Определете суперкласа: супер() приема два аргумента – текущия клас и екземпляра – които не е необходимо да предавате изрично. Той използва тази информация, за да определи суперкласа за делегиране на извикването на метода. Той прави това чрез изследване на класовата йерархия и MRO.
  3. Извикайте метода в суперкласа: След като бъде определен суперкласът, супер() ви позволява да извиквате неговите методи, сякаш ги извиквате директно от подкласа. Това ви позволява да разширите или замените методи, докато все още използвате оригиналната реализация от суперкласа.

Използване на super() в конструктор на клас

Използвайки супер() в конструктор на клас е обичайна практика, тъй като често ще искате да инициализирате общи атрибути в родителския клас и по-специфични в дъщерния.

За да демонстрирате това, дефинирайте клас Python, баща, което а син клас наследява от:

classFather:
def__init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name

classSon(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 = hobby

defget_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())

Вътре в син конструктор, извикването на супер().init() извиква баща конструктор на клас, предавайки го първо име и фамилия като параметри. Това гарантира, че баща клас все още може да зададе правилно атрибутите на името, дори на a син обект.

Ако не се обадите супер() в конструктор на клас, конструкторът на неговия родителски клас няма да се изпълнява. Това може да доведе до нежелани последствия, като липсващи инициализации на атрибути или непълна настройка на състоянието на родителския клас:

...
classSon(Father):
def__init__(self, first_name, last_name, age, hobby):
self.age = age
self.hobby = hobby
...

Ако сега се опитате да се обадите на get_info метод, той ще повиши an AttributeError тъй като self.first_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)

The син клас наследява от баща и има своето говори метод. The говори метод на син клас използва супер().говори() да се обадите на говори метод на баща клас. Това му позволява да включи съобщението от родителския клас, докато го разширява със съобщение, специфично за дъщерния клас.

Неуспешно използване супер() в метод, който замества друг, означава, че функционалността, присъстваща в метода на родителския клас, няма да влезе в сила. Това води до пълна подмяна на поведението на метода, което може да доведе до поведение, което не сте възнамерявали.

Разбиране на реда за разрешаване на метода

Редът за разрешаване на метода (MRO) е редът, в който Python търси предшественици, когато имате достъп до метод или атрибут. MRO помага на Python да определи кой метод да извика, когато съществуват множество йерархии на наследяване.

classNigeria():
defculture(self):
print("Nigeria's culture")

classAfrica():
defculture(self):
print("Africa's culture")

Ето какво се случва, когато създадете екземпляр на Лагос клас и се обадете на култура метод:

  1. Python започва с търсене на култура метод в Лагос самия клас. Ако го намери, извиква метода. Ако не, се преминава към втора стъпка.
  2. Ако не намери култура метод в Лагос клас, Python разглежда базовите класове в реда, в който се появяват в дефиницията на класа. В такъв случай, Лагос наследява първо от Африка и след това от Нигерия. Така че Python ще търси култура метод в Африка първи.
  3. Ако не намери култура метод в Африка клас, Python ще търси в Нигерия клас. Това поведение продължава, докато достигне края на йерархията и извежда грешка, ако не може да намери метода в някой от суперкласовете.

Резултатът показва реда на разрешаване на метода на Лагос, започвайки отляво надясно.

Често срещани клопки и най-добри практики

При работа с супер(), има някои често срещани капани, които трябва да избягвате.

  1. Обърнете внимание на реда за разрешаване на метода, особено в сценарии с множествено наследяване. Ако трябва да използвате сложно множествено наследяване, трябва да сте запознати с C3 Алгоритъм за линеаризация които Python използва за определяне на MRO.
  2. Избягвайте кръгови зависимости в йерархията на вашите класове, които могат да доведат до непредсказуемо поведение.
  3. Документирайте кода си ясно, особено при използване супер() в сложни класови йерархии, за да стане по-разбираем за други разработчици.

Използвайте super() по правилния начин

на Python супер() е мощна функция, когато работите с наследяване и замяна на метод. Разбиране как супер() работи и следването на най-добрите практики ще ви позволи да създадете по-поддържан и ефективен код във вашите проекти на Python.