Arv er nyttig, men du kan låse opp dets fulle potensiale ved å gjenbruke kode fra basisklasser.

Viktige takeaways

  • Pythons super()-funksjon lar deg kalle superklassemetoder fra en underklasse, noe som gjør det enklere å implementere arv og metodeoverstyring.
  • Super()-funksjonen er nært knyttet til Method Resolution Order (MRO) i Python, som bestemmer rekkefølgen som forfedreklasser søkes etter metoder eller attributter i.
  • Å bruke super() i klassekonstruktører er en vanlig praksis for å initialisere vanlige attributter i overordnet klasse og mer spesifikke i barneklassen. Unnlatelse av å bruke super() kan føre til utilsiktede konsekvenser, for eksempel manglende attributtinitialiseringer.

En av kjernefunksjonene til Python er OOP-paradigmet, som du kan bruke til å modellere virkelige enheter og deres relasjoner.

Når du arbeider med Python-klasser, vil du ofte bruke arv og overstyre en superklasses attributter eller metoder. Python gir en super() funksjon som lar deg kalle superklassens metoder fra underklassen.

Hva er super() og hvorfor trenger du det?

Ved å bruke arv kan du lage en ny Python-klasse som arver funksjonene til en eksisterende klasse. Du kan også overstyre metoder for superklassen i underklassen, og gi alternative implementeringer. Det kan imidlertid være lurt å bruke den nye funksjonaliteten i tillegg til den gamle, i stedet for den. I dette tilfellet, super() er nyttig.

Du kan bruke super() funksjon for å få tilgang til superklasseattributter og påkalle metoder for superklassen. Super er avgjørende for Objektorientert programmering fordi det gjør det lettere å implementere arv og metodeoverstyring.

Hvordan fungerer super()?

Internt, super() er nært knyttet til Metode Oppløsningsrekkefølge (MRO) i Python, som C3-lineariseringsalgoritmen bestemmer.

Dette er hvordan super() virker:

  1. Bestem gjeldende klasse og forekomst: Når du ringer super() inne i en metode til en underklasse, finner Python automatisk ut gjeldende klasse (klassen som inneholder metoden som kalte super()) og forekomsten av den klassen (dvs. selv-).
  2. Bestem superklassen: super() tar to argumenter – den nåværende klassen og instansen – som du ikke trenger å bestå eksplisitt. Den bruker denne informasjonen til å bestemme superklassen for å delegere metodekallet. Den gjør dette ved å undersøke klassehierarkiet og MRO.
  3. Påkall metoden på Superklassen: Når det er bestemt superklassen, super() lar deg kalle metodene som om du ringer dem direkte fra underklassen. Dette lar deg utvide eller overstyre metoder mens du fortsatt bruker den originale implementeringen fra superklassen.

Bruke super() i en klassekonstruktør

Ved hjelp av super() i en klassekonstruktør er vanlig praksis, siden du ofte vil initialisere vanlige attributter i den overordnede klassen og mer spesifikke i barnet.

For å demonstrere dette, definer en Python-klasse, Far, som en Sønn 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())

Inne i Sønn konstruktør, oppfordringen til super().init() påkaller Far klassekonstruktør, bestått den fornavn og etternavn som parametere. Dette sikrer at Far klasse kan fortsatt sette navneattributtene riktig, selv på en Sønn gjenstand.

Hvis du ikke ringer super() i en klassekonstruktør vil ikke konstruktøren til dens overordnede klasse kjøre. Dette kan føre til utilsiktede konsekvenser, for eksempel manglende attributtinitieringer eller ufullstendig oppsett av overordnet klasses tilstand:

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

Hvis du nå prøver å ringe til få informasjon metode, vil det heve en AttributeError fordi det self.first_name og selv.etternavn attributter er ikke initialisert.

Bruker super() i klassemetoder

Du kan bruke super() i andre metoder, bortsett fra konstruktører, på akkurat samme måte. Dette lar deg utvide eller overstyre oppførselen til 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)

De Sønn klasse arver fra Far og har sin snakke metode. De snakke metoden for Sønn klasse bruker super().speak() å ringe til snakke metoden for Far klasse. Dette lar den inkludere meldingen fra den overordnede klassen mens den utvides med en melding som er spesifikk for underklassen.

Ikke bruk super() i en metode som overstyrer en annen, betyr det at funksjonaliteten som finnes i den overordnede klassemetoden ikke trer i kraft. Dette resulterer i en fullstendig erstatning av metodeatferden, noe som kan føre til atferd du ikke hadde til hensikt.

Forstå Metode Resolution Order

Method Resolution Order (MRO) er rekkefølgen der Python søker etter forfedreklasser når du får tilgang til en metode eller et attributt. MRO hjelper Python med å bestemme hvilken metode som skal kalles når flere arvehierarkier eksisterer.

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

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

Her er hva som skjer når du oppretter en forekomst av Lagos klasse og ring kultur metode:

  1. Python starter med å se etter kultur metode i Lagos klasse selv. Hvis den finner den, kaller den metoden. Hvis ikke, går den videre til trinn to.
  2. Hvis den ikke finner kultur metode i Lagos klasse, ser Python på basisklassene i den rekkefølgen de vises i klassedefinisjonen. I dette tilfellet, Lagos arver først fra Afrika og så fra Nigeria. Så, Python vil se etter kultur metode i Afrika først.
  3. Hvis den ikke finner kultur metode i Afrika klasse, vil Python deretter se i Nigeria klasse. Denne virkemåten fortsetter til den når slutten av hierarkiet og gir en feilmelding hvis den ikke finner metoden i noen av superklassene.

Utdataene viser metodeoppløsningsrekkefølgen på Lagos, fra venstre til høyre.

Vanlige fallgruver og beste praksis

Når du jobber med super(), er det noen vanlige fallgruver å unngå.

  1. Vær oppmerksom på metodeoppløsningsrekkefølgen, spesielt i flere scenarier for arv. Hvis du trenger å bruke kompleks multippel arv, bør du være kjent med C3 Lineariseringsalgoritme som Python bruker for å bestemme MRO.
  2. Unngå sirkulære avhengigheter i klassehierarkiet ditt, noe som kan føre til uforutsigbar oppførsel.
  3. Dokumenter koden din tydelig, spesielt ved bruk super() i komplekse klassehierarkier, for å gjøre det mer forståelig for andre utviklere.

Bruk super() på riktig måte

Python sin super() funksjon er en kraftig funksjon når du jobber med arv og metodeoverstyring. Forstå hvordan super() fungerer og å følge beste praksis lar deg lage mer vedlikeholdbar og effektiv kode i Python-prosjektene dine.