Contents

Använda super()-funktionen i Python-klasser

Viktiga slutsatser

Pythons användning av funktionen super() underlättar anrop av metoder i en underklass genom åtkomst till dess superklass, vilket förbättrar processen för implementering av arv och metodåsidosättande på ett elegant sätt.

Funktionen super() har en viktig koppling till Method Resolution Order (MRO) i Python, som styr i vilken ordning förfädernas klasser granskas för metoder och egenskaper under metodresolution.

Att använda super() inom konstruktorn för en klass är ett vanligt tillvägagångssätt för att fastställa gemensamma egenskaper i den överordnade klassen medan man definierar mer specifika egenskaper i den underordnade klassen. Om super() inte implementeras kan det leda till oönskade resultat, inklusive utelämnad attributinitialisering.

En av de grundläggande aspekterna av Python är dess paradigm för objektorienterad programmering (OOP), som gör det möjligt att skapa modeller som på ett strukturerat sätt representerar verkliga objekt och deras inbördes kopplingar.

I samband med programmering med Python är det vanligt att använda arv för att modifiera eller ersätta egenskaper eller funktioner hos en klass överordnade enhet. Språket erbjuder en praktisk mekanism som kallas “super()"-funktionen, som gör det möjligt att anropa metoderna för den överordnade klassen från den underordnade klassen.

Vad är super() och varför behöver du den?

Genom att ärva från en befintlig klass kan man skapa en ny klass med liknande attribut och beteenden genom arvsprocessen. Dessutom kan man välja att åsidosätta specifika metoder inom underklassen för att skapa sin egen unika implementering. Även om denna nya funktionalitet kan vara önskvärd, finns det fall där det är att föredra att använda både den ursprungliga och den nyligen implementerade funktionaliteten samtidigt. I sådana fall kan funktionen super() användas för att integrera båda uppsättningarna av funktioner i underklassen.

För att utnyttja en superklass attribut och metoder i objektorienterad programmering kan man använda funktionen super() . Denna funktion spelar en avgörande roll eftersom den underlättar implementeringen av arv och metodöversättning, som är grundläggande begrepp i objektorienterad programmering.

Hur fungerar super()?

Internt är beteendet hos funktionen super() sammanflätat med begreppet Method Resolution Order (MRO), en mekanism som bestäms av C3-linjäriseringsalgoritmen i Python.

Så här fungerar super():

När super() anropas inom en metod för en underklass i Python, identifierar språket automatiskt både den aktuella klassen, som innehåller den anropande metoden, samt instansen av denna klass som representeras av self .

⭐ Bestäm superklassen : super() tar två argument - den aktuella klassen och instansen - som du inte behöver skicka explicit. Den använder denna information för att bestämma vilken superklass som ska delegera metodanropet. Detta görs genom att undersöka klasshierarkin och MRO.

När en superklass har identifierats, tillåter funktionen super() anrop av dess metoder som om de anropades direkt från underklassen. Detta gör det möjligt att både utöka och åsidosätta superklassens metoder, samtidigt som man använder den ursprungliga implementeringen som tillhandahålls av superklassen.

Använda super() i en klasskonstruktör

Att integrera användningen av super()-metoden i klasskonstruktörer är ett vanligt tillvägagångssätt, eftersom det möjliggör initialisering av delade egenskaper mellan syskonklasser samtidigt som unika egenskaper tillåts i varje enskild avkomma.

För att illustrera begreppet arv i objektorienterad programmering med Python, kan vi skapa en klass “Father” som fungerar som basklass för en annan klass som heter “Son”. Klassen “Son” kommer att ärva egenskaper och metoder från sin föräldraklass, “Father”, och därigenom visa hur arv möjliggör återanvändning av kod och modularitet.

 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):
        # Call the parent class constructor (Father)
        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}"

# Create an instance of the Son class
son = Son("Pius", "Effiong", 25, "Playing Guitar")

# Access attributes
print(son.get_info())

Inom ramen för Son -klassens konstruktor utförs imperativet att anropa sin föräldraklass genom den fantastiska handlingen att anropa super() -funktionen. Denna viktiga åtgärd utlöser initieringen av den faderliga Fader klasskonstruktorn, vilket ger två uppskattade, överordnade kvalificerare i form av variablerna first_name och last_name . På detta sätt behåller klassen Father förmågan att korrekt uppnå och tilldela dessa nominella beteckningar, trots instansiering av en Son .

/sv/images/using-super-in-class-constructor.jpg

Om metoden super() inte anropas inom konstruktionen

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

Om du försöker anropa metoden get_info vid denna tidpunkt kommer det att leda till att ett AttributeError skapas, eftersom de self. first_name och self.last_name attributen ännu inte har initialiserats.

/sv/images/trying-to-use-parent-attributes-without-super.jpg

Använda super() i klassmetoder

Man kan använda super()-funktionen inte bara inom ramen för konstruktorprocedurer utan även i en mängd olika metoder för att antingen förstärka eller ersätta funktionaliteten i moderklassens metodologiska tillvägagångssätt.

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

class Son(Father):
    def speak(self):
        # Call the parent class's speak method using super()
        parent_greeting = super().speak()
        return f"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)

Klassen Son i Python är utformad för att ärva egenskaper och metoder från sin förälder eller klassen Father , inklusive metoden speak() . Genom att använda funktionen super().speak() inom Son -klassens speak() -metod, kan den effektivt anropa den ursprungliga speak() -metoden för Father -klassen, samtidigt som den också införlivar ytterligare information eller meddelanden som är unika för Son -klassen.

/sv/images/using-super-in-class-mthod.jpg

Om en metod åsidosätter en annan utan att använda den medföljande funktionen super() , kommer den avsedda funktionen från den överordnade klassen inte att utföras. Följaktligen kan detta resultera i oavsiktligt beteende på grund av att en helt ny och distinkt metodik ersätter den ursprungliga funktionaliteten.

Förstå Method Resolution Order

Method Resolution Order (MRO) är en prioritetshierarki som bestämmer i vilken ordning Python ska söka efter metoder och attribut i komplexa klassstrukturer med flera arv. Denna mekanism säkerställer att lämplig metod anropas baserat på tillgängliga alternativ inom respektive föräldraklass, vilket löser eventuella tvetydigheter som uppstår på grund av överlappande definitioner.

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

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

När Lagos-klassen instansieras och dess kulturmetod anropas sker ett antal händelser som bidrar till objektets övergripande funktionalitet. Koden exekveras genom flera steg som omfattar datamanipulation, informationshämtning från externa källor och tillämpning av olika algoritmer för att analysera kulturella aspekter baserat på inparametrar som tillhandahålls av användaren eller standardvärden som anges i konstruktorn. Slutresultatet är en omfattande bedömning av den angivna stadens kulturella attribut som representeras av Lagos-klassen.

Python söker först efter metoden culture i själva klassen Lagos . Om denna metod hittas och är tillgänglig, fortsätter algoritmen med att åberopa den. Om det däremot inte finns någon sådan metod eller om den inte går att komma åt, går processen vidare till nästa fas.

Om klassen Lagos inte har en culture() metod, kommer Python att söka efter metoden i basklasserna i klasshierarkin, med början med de som anges efter kolon ( : ), som ärvs av klassen Lagos . I detta exempel definieras klassen Lagos att först ärva från klassen Africa och därefter från klassen Nigeria . Om klassen Lagos inte innehåller en egen implementering av metoden culture() , kommer Python därför att försöka hitta metoden i klassen Africa innan den söker i klassen Nigeria .

Sökningen efter en kulturspecifik metod inom en given klasshierarki fortsätter genom en serie av nästlade klasser, där varje efterföljande klass undersöks ifall den önskade metoden finns i den. Om metoden inte upptäcks på den första undersökningsnivån, nämligen den afrikanska klassen, flyttar Python sitt fokus till den näst högsta klassen i den hierarkiska strukturen, vilket i detta fall motsvarar den nigerianska klassen. Denna process upprepas allteftersom man går ner i klassträdet, från det mest allmänna till det minst specifika, tills den eftersökta metoden inte kan hittas i någon av de superklasser som påträffas. I det läget skapas ett undantag som visar att sökningen misslyckats.

/sv/images/the-mothod-resolution-order.jpg

Metodresolutionsordningen (MRO) för Lagos visas linjärt, från vänster mot höger.

Vanliga fallgropar och bästa praxis

När man använder funktionen super() är det viktigt att vara medveten om vissa potentiella felsteg för att säkerställa en smidig och effektiv upplevelse.

⭐ Var uppmärksam på metodupplösningsordningen, särskilt i scenarier med flera arv. Om du behöver använda komplex multipel arv, bör du vara bekant med C3 Linearization algoritm som Python använder för att bestämma MRO.

Cirkulära beroenden inom en klasshierarki bör undvikas eftersom de kan leda till oregelbundet och svårförutsägbart beteende.

När man arbetar med invecklade klasshierarkier som innefattar användning av funktionen super() är det viktigt att upprätthålla en tydlig och väldokumenterad kodbas. Detta säkerställer inte bara korrekt funktionalitet utan främjar också förståelsen bland andra utvecklare som kan behöva arbeta med eller ändra koden i framtiden. Genom att ge kortfattade men informativa kommentarer kan du förbättra läsbarheten och underhållet av ditt projekt, underlätta samarbete och minska potentiella fel eller förvirring.

Använd super() på rätt sätt

Pythons användning av funktionen super() utgör en oumbärlig aspekt av dess objektorienterade programmeringsparadigm, särskilt i förhållande till underlättandet av arv och metodöverskridanden. Genom att förstå komplexiteten i denna funktionella enhet och följa etablerad bästa praxis kan man utveckla mer hållbara och resursstarka programvaruapplikationer inom Python-ekosystemet.