Bruke super()-funksjonen i Python-klasser

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 har 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 er super() nyttig.

Du kan bruke super()-funksjonen 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.

  8 Enterprise Survey-programvare for å transformere datainnsamlingsstrategien

Hvordan fungerer super()?

Internt er super() nært knyttet til Method Resolution Order (MRO) i Python, som C3-lineariseringsalgoritmen bestemmer.

Slik fungerer super():

  • Bestem gjeldende klasse og forekomst: Når du kaller super() inne i en metode i en underklasse, finner Python automatisk ut gjeldende klasse (klassen som inneholder metoden som kalte super()) og forekomsten av den klassen (dvs. selv) .
  • 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.
  • Kalle frem metoden på superklassen: Når det er bestemt superklassen, lar super() deg kalle metodene som om du kaller 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

    Å bruke 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, Father, som en Son-klasse arver fra:

     class Father:
        def __init__(self, first_name, last_name):
            self.first_name = first_name
            self.last_name = last_name

    class Son(Father):
        def __init__(self, first_name, last_name, age, hobby):
            
            super().__init__(first_name, last_name)

            self.age = age
            self.hobby = hobby

        def get_info(self):
            return f"Son's Name: {self.first_name} {self.last_name}, \
    Son's Age: {self.age}, Son's Hobby: {self.hobby}"


    son = Son("Pius", "Effiong", 25, "Playing Guitar")


    print(son.get_info())

    Inne i Son-konstruktøren påkaller kallet til super().init() Father-klassekonstruktøren, og sender den fornavn og etternavn som parametere. Dette sikrer at Fader-klassen fortsatt kan sette navneattributtene riktig, selv på et Son-objekt.

      Slipp løs kraften i innovativ tenkning

    Hvis du ikke kaller 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:

     ...
    class Son(Father):
        def __init__(self, first_name, last_name, age, hobby):
            self.age = age
            self.hobby = hobby
    ...

    Hvis du nå prøver å kalle get_info-metoden, vil det oppstå en AttributeError fordi attributtene self.first_name og self.last_name ikke er 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.

     class Father:
        def speak(self):
            return "Hello from Father"

    class Son(Father):
        def speak(self):
            
            parent_greeting = super().speak()
            return f"Hello from Son\n{parent_greeting}"


    son = Son()


    son_greeting = son.speak()

    print(son_greeting)

    Son-klassen arver fra Faderen og har sin talemetode. Speak-metoden til Son-klassen bruker super().speak() for å kalle Speak-metoden til Fader-klassen. Dette lar den inkludere meldingen fra den overordnede klassen mens den utvides med en melding som er spesifikk for underklassen.

    Unnlatelse av å bruke super() i en metode som overstyrer en annen betyr at funksjonaliteten som er tilstede 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.

     class Nigeria():
        def culture(self):
            print("Nigeria's culture")

    class Africa():
       def culture(self):
           print("Africa's culture")

    Her er hva som skjer når du oppretter en forekomst av Lagos-klassen og kaller kulturmetoden:

      Hvordan oppgradere til Pop_OS 21.04
  • Python starter med å se etter kulturmetoden i selve Lagos-klassen. Hvis den finner den, kaller den metoden. Hvis ikke, går den videre til trinn to.
  • Hvis den ikke finner kulturmetoden i Lagos-klassen, ser Python på basisklassene i den rekkefølgen de vises i klassedefinisjonen. I dette tilfellet arver Lagos først fra Afrika og deretter fra Nigeria. Så, Python vil se etter kulturmetoden i Afrika først.
  • Finner den ikke kulturmetoden i Afrika-klassen, vil Python lete i Nigeria-klassen. 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 til Lagos, fra venstre til høyre.

    Vanlige fallgruver og beste praksis

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

  • 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.
  • Unngå sirkulære avhengigheter i klassehierarkiet ditt, noe som kan føre til uforutsigbar oppførsel.
  • Dokumenter koden din tydelig, spesielt når du bruker super() i komplekse klassehierarkier, for å gjøre den mer forståelig for andre utviklere.
  • Bruk super() på riktig måte

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