Arv er nyttigt, men du kan låse op for dets fulde potentiale ved at genbruge kode fra basisklasser.

Nøgle takeaways

  • Pythons super()-funktion giver dig mulighed for at kalde superklassemetoder fra en underklasse, hvilket gør det nemmere at implementere nedarvning og metodetilsidesættelse.
  • Super()-funktionen er nært beslægtet med Method Resolution Order (MRO) i Python, som bestemmer rækkefølgen, hvori forfaderklasser søges efter metoder eller attributter.
  • Brug af super() i klassekonstruktører er en almindelig praksis at initialisere fælles attributter i den overordnede klasse og mere specifikke i den underordnede klasse. Undladelse af at bruge super() kan føre til utilsigtede konsekvenser, såsom manglende attributinitialiseringer.

En af kerneegenskaberne i Python er dets OOP-paradigme, som du kan bruge til at modellere virkelige enheder og deres relationer.

Når du arbejder med Python-klasser, vil du ofte bruge arv og tilsidesætte en superklasses attributter eller metoder. Python giver en super() funktion, der lader dig kalde superklassens metoder fra underklassen.

Hvad er super() og hvorfor har du brug for det?

Ved at bruge arv, kan du lave en ny Python-klasse, der arver funktionerne fra en eksisterende klasse. Du kan også tilsidesætte superklassens metoder i underklassen, hvilket giver alternative implementeringer. Du vil dog måske bruge den nye funktionalitet ud over den gamle i stedet for. I dette tilfælde, super() er nyttig.

Du kan bruge super() funktion til at få adgang til superklasseattributter og påberåbe superklassens metoder. Super er afgørende for objektorienteret programmering fordi det gør det nemmere at implementere arv og metodetilsidesættelse.

Hvordan virker super()?

Internt, super() er tæt forbundet med Metode Resolution Order (MRO) i Python, som C3-lineariseringsalgoritmen bestemmer.

Sådan gør du super() arbejder:

  1. Bestem den aktuelle klasse og instans: Når du ringer super() inde i en metode i en underklasse finder Python automatisk ud af den aktuelle klasse (klassen, der indeholder metoden, der kaldte super()) og forekomsten af ​​den pågældende klasse (dvs. selv).
  2. Bestem superklassen: super() tager to argumenter – den aktuelle klasse og instansen – som du ikke behøver at videregive eksplicit. Den bruger disse oplysninger til at bestemme superklassen til at uddelegere metodekaldet. Det gør den ved at undersøge klassehierarkiet og MRO.
  3. Påberåb metoden på Superklassen: Når det er bestemt superklassen, super() giver dig mulighed for at kalde dets metoder, som om du kalder dem direkte fra underklassen. Dette giver dig mulighed for at udvide eller tilsidesætte metoder, mens du stadig bruger den originale implementering fra superklassen.

Brug af super() i en klassekonstruktør

Ved brug af super() i en klassekonstruktør er almindelig praksis, da du ofte vil initialisere fælles attributter i den overordnede klasse og mere specifikke i barnet.

For at demonstrere dette, definere en Python-klasse, Far, som en Søn klasse arver fra:

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

Inde i Søn konstruktør, opfordringen til super().init() påberåber sig Far klasse konstruktør, bestå det fornavn og efternavn som parametre. Dette sikrer, at Far klasse kan stadig indstille navneattributterne korrekt, selv på en Søn objekt.

Hvis du ikke ringer super() i en klassekonstruktør vil konstruktøren af ​​dens overordnede klasse ikke køre. Dette kan føre til utilsigtede konsekvenser, såsom manglende attributinitialiseringer eller ufuldstændig opsætning af den overordnede klasses tilstand:

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

Hvis du nu prøver at ringe til få information metode, vil det hæve en AttributError fordi selv.fornavn og selv.efternavn attributter er ikke blevet initialiseret.

Brug af super() i klassemetoder

Du kan bruge super() i andre metoder, bortset fra konstruktører, på præcis samme måde. Dette lader dig udvide eller tilsidesætte adfærden for superklassens metode.

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)

Det Søn klasse arver fra Far og har sin tale metode. Det tale metoden til Søn klasse bruger super().speak() at ringe til tale metoden til Far klasse. Dette giver den mulighed for at inkludere beskeden fra den overordnede klasse, mens den udvides med en besked, der er specifik for den underordnede klasse.

Manglende brug super() i en metode, der tilsidesætter en anden, betyder den funktionalitet, der findes i den overordnede klassemetode, ikke vil træde i kraft. Dette resulterer i en fuldstændig udskiftning af metodeadfærden, hvilket kan føre til adfærd, du ikke havde til hensigt.

Forståelse af metodeopløsningsorden

Method Resolution Order (MRO) er den rækkefølge, hvori Python søger efter forfædreklasser, når du tilgår en metode eller en attribut. MRO hjælper Python med at bestemme, hvilken metode der skal kaldes, når der findes flere arvehierarkier.

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

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

Her er, hvad der sker, når du opretter en forekomst af Lagos klasse og ring til kultur metode:

  1. Python starter med at lede efter kultur metode i Lagos klasse selv. Hvis den finder den, kalder den metoden. Hvis ikke, går den videre til trin to.
  2. Hvis den ikke finder kultur metode i Lagos klasse, ser Python på basisklasserne i den rækkefølge, de vises i klassedefinitionen. I dette tilfælde, Lagos arver først fra Afrika og så fra Nigeria. Så Python vil lede efter kultur metode i Afrika først.
  3. Hvis den ikke finder kultur metode i Afrika klasse, vil Python så kigge i Nigeria klasse. Denne adfærd fortsætter, indtil den når slutningen af ​​hierarkiet og giver en fejl, hvis den ikke kan finde metoden i nogen af ​​superklasserne.

Outputtet viser metodeopløsningsrækkefølgen på Lagos, startende fra venstre mod højre.

Almindelige faldgruber og bedste praksis

Når man arbejder med super(), er der nogle almindelige faldgruber at undgå.

  1. Vær opmærksom på metodeopløsningsbekendtgørelsen, især i flere scenarier med arv. Hvis du skal bruge kompleks multipel arv, bør du være bekendt med C3 Lineariseringsalgoritme som Python bruger til at bestemme MRO.
  2. Undgå cirkulære afhængigheder i dit klassehierarki, hvilket kan føre til uforudsigelig adfærd.
  3. Dokumenter din kode tydeligt, især ved brug super() i komplekse klassehierarkier, for at gøre det mere forståeligt for andre udviklere.

Brug super() på den rigtige måde

Python's super() funktion er en kraftfuld funktion, når du arbejder med arv og metodetilsidesættelse. Forstå hvordan super() fungerer, og ved at følge bedste praksis kan du skabe mere vedligeholdelig og effektiv kode i dine Python-projekter.