Nasljeđivanje je korisno, ali možete otključati njegov puni potencijal ponovnom upotrebom koda iz osnovnih klasa.

Ključni zahvati

  • Pythonova funkcija super() omogućuje vam pozivanje metoda nadklase iz podklase, što olakšava implementaciju nasljeđivanja i nadjačavanja metoda.
  • Funkcija super() usko je povezana s Redoslijedom razlučivanja metoda (MRO) u Pythonu, koji određuje redoslijed kojim se pretražuju klase predaka za metode ili atribute.
  • Korištenje super() u konstruktorima klasa uobičajena je praksa za inicijaliziranje uobičajenih atributa u roditeljskoj klasi i specifičnijih u podređenoj klasi. Neupotreba super() može dovesti do neželjenih posljedica, kao što je nedostatak inicijalizacije atributa.

Jedna od ključnih značajki Pythona je njegova OOP paradigma, koju možete koristiti za modeliranje entiteta stvarnog svijeta i njihovih odnosa.

Kada radite s Python klasama, često ćete koristiti nasljeđivanje i nadjačati atribute ili metode superklase. Python pruža a super() funkcija koja vam omogućuje pozivanje metoda superklase iz podklase.

Što je super() i zašto vam treba?

Koristeći nasljeđivanje, možete napraviti novu Python klasu koja nasljeđuje značajke postojeće klase. Također možete nadjačati metode nadklase u podklasi, pružajući alternativne implementacije. Međutim, možda biste trebali koristiti novu funkcionalnost uz staru, a ne umjesto nje. U ovom slučaju, super() je koristan.

Možete koristiti super() funkcija za pristup atributima nadklase i pozivanje metoda nadklase. Super je neophodan za objektno orijentirano programiranje jer olakšava implementaciju nasljeđivanja i nadjačavanja metode.

Kako radi super()?

Interno, super() usko je povezan s Redoslijed rješenja metode (MRO) u Pythonu, što određuje algoritam C3 linearizacije.

Evo kako super() djela:

  1. Odredite trenutnu klasu i instancu: Kada zovete super() unutar metode podklase, Python automatski otkriva trenutnu klasu (klasa koja sadrži metodu koja je pozvala super()) i instanca te klase (tj. sebe).
  2. Odredite nadklasu: super() uzima dva argumenta — trenutnu klasu i instancu — koje ne morate eksplicitno proslijediti. Koristi ove informacije za određivanje superklase za delegiranje poziva metode. To čini ispitivanjem hijerarhije klasa i MRO-a.
  3. Pozovite metodu na superklasi: Nakon što se odredi superrazred, super() omogućuje pozivanje njegovih metoda kao da ih pozivate izravno iz podklase. To vam omogućuje da proširite ili nadjačate metode dok još uvijek koristite izvornu implementaciju iz superklase.

Korištenje super() u konstruktoru klase

Korištenje super() u konstruktoru klase je uobičajena praksa, budući da ćete često htjeti inicijalizirati zajedničke atribute u roditeljskoj klasi i specifičnije u podređenoj.

Da bi to pokazao, definiraju Python klasu, Otac, koji a Sin klasa nasljeđuje od:

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

Unutar Sin konstruktor, poziv za super().init() poziva se na Otac konstruktor klase, prolazeći ga ime i prezime kao parametri. Ovo osigurava da Otac klasa još uvijek može ispravno postaviti atribute imena, čak i na a Sin objekt.

Ako ne nazovete super() u konstruktoru klase, konstruktor njegove nadređene klase neće se izvoditi. To može dovesti do neželjenih posljedica, kao što su nedostajuće inicijalizacije atributa ili nepotpuno postavljanje stanja nadređene klase:

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

Ako sada pokušate nazvati dobiti informacije metoda, to će povećati an AttributeError jer sebe.ime i sebe.prezime atributi nisu inicijalizirani.

Korištenje super() u metodama klase

Možeš koristiti super() u drugim metodama, osim konstruktora, na isti način. To vam omogućuje proširenje ili nadjačavanje ponašanja metode superklase.

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 Sin klasa nasljeđuje od Otac i ima svoje govoriti metoda. The govoriti metoda Sin klasa koristi super().govori() nazvati govoriti metoda Otac razreda. To mu omogućuje da uključi poruku iz nadređene klase dok je proširuje porukom specifičnom za podređenu klasu.

Neuspješno korištenje super() u metodi koja nadjačava drugu znači da funkcionalnost prisutna u metodi nadređene klase neće stupiti na snagu. To rezultira potpunom zamjenom ponašanja metode, što može dovesti do ponašanja koje niste namjeravali.

Razumijevanje Redoslijeda razlučivanja metode

Redoslijed razlučivanja metode (MRO) je redoslijed kojim Python pretražuje klase predaka kada pristupite metodi ili atributu. MRO pomaže Pythonu odrediti koju metodu pozvati kada postoji više hijerarhija nasljeđivanja.

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

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

Evo što se događa kada stvorite instancu Lagos razreda i nazovite Kultura metoda:

  1. Python počinje traženjem Kultura metoda u Lagos sama klasa. Ako ga pronađe, poziva metodu. Ako nije, prelazi se na drugi korak.
  2. Ako ne pronađe Kultura metoda u Lagos klase, Python gleda osnovne klase redoslijedom kojim se pojavljuju u definiciji klase. U ovom slučaju, Lagos nasljeđuje prvo od Afrika a zatim iz Nigerija. Dakle, Python će tražiti Kultura metoda u Afrika prvi.
  3. Ako ne pronađe Kultura metoda u Afrika klasi, Python će tada tražiti u Nigerija razreda. Ovo se ponašanje nastavlja sve dok ne dođe do kraja hijerarhije i izbacuje pogrešku ako ne može pronaći metodu u bilo kojoj od superklasa.

Izlaz prikazuje redoslijed razrješenja metode od Lagos, počevši s lijeva na desno.

Uobičajene zamke i najbolji primjeri iz prakse

Prilikom rada sa super(), postoje neke uobičajene zamke koje treba izbjegavati.

  1. Imajte na umu Redoslijed rješavanja metode, posebno u scenarijima višestrukog nasljeđivanja. Ako trebate koristiti složeno višestruko nasljeđivanje, trebali biste biti upoznati s C3 algoritam linearizacije koje Python koristi za određivanje MRO-a.
  2. Izbjegavajte kružne ovisnosti u hijerarhiji klasa koje mogu dovesti do nepredvidivog ponašanja.
  3. Jasno dokumentirajte svoj kod, posebno kada se koristi super() u složenim hijerarhijama klasa, kako bi bio razumljiviji drugim programerima.

Koristite super() na pravi način

Pythonova super() funkcija je moćna značajka kada radite s nasljeđivanjem i nadjačavanjem metode. Razumijevanje kako super() radi, a slijedeći najbolje prakse omogućit će vam da stvorite učinkovitiji i održiviji kod u svojim Python projektima.