Overerving is nuttig, maar u kunt het volledige potentieel ervan ontsluiten door code uit basisklassen te hergebruiken.
Belangrijkste leerpunten
- Met de super()-functie van Python kun je superklasse-methoden aanroepen vanuit een subklasse, waardoor het eenvoudiger wordt om overerving en methode-overschrijving te implementeren.
- De functie super() is nauw verwant aan de Method Resolution Order (MRO) in Python, die de volgorde bepaalt waarin voorouderklassen worden doorzocht op methoden of attributen.
- Het gebruik van super() in klassenconstructors is een gangbare praktijk om gemeenschappelijke attributen in de bovenliggende klasse en meer specifieke attributen in de onderliggende klasse te initialiseren. Het niet gebruiken van super() kan tot onbedoelde gevolgen leiden, zoals ontbrekende attribuutinitialisaties.
Een van de kernfuncties van Python is het OOP-paradigma, dat je kunt gebruiken om entiteiten uit de echte wereld en hun relaties te modelleren.
Wanneer u met Python-klassen werkt, maakt u vaak gebruik van overerving en overschrijft u de attributen of methoden van een superklasse. Python biedt een
super() functie waarmee u de methoden van de superklasse vanuit de subklasse kunt aanroepen.Wat is super() en waarom heb je het nodig?
Met behulp van overerving kun je een nieuwe Python-klasse maken die de kenmerken van een bestaande klasse overneemt. U kunt ook methoden van de superklasse in de subklasse overschrijven, waardoor alternatieve implementaties worden geboden. Het kan echter zijn dat u de nieuwe functionaliteit naast de oude wilt gebruiken, in plaats van in plaats daarvan. In dit geval, super() is nuttig.
U kunt gebruik maken van de super() functie om toegang te krijgen tot superklasse-attributen en methoden van de superklasse aan te roepen. Super is essentieel voor object georiënteerd programmeren omdat het het eenvoudiger maakt om overerving en methode-overschrijving te implementeren.
Hoe werkt super()?
Intern, super() is nauw verwant aan de Methode Resolutie Volgorde (MRO) in Python, wat het C3 Linearisatie-algoritme bepaalt.
Hier is hoe super() werken:
- Bepaal de huidige klasse en instantie: Wanneer je belt super() binnen een methode van een subklasse zoekt Python automatisch de huidige klasse uit (de klasse die de methode bevat die heeft aangeroepen super()) en de instantie van die klasse (d.w.z. zelf).
- Bepaal de superklasse: super() heeft twee argumenten nodig (de huidige klasse en de instantie) die u niet expliciet hoeft door te geven. Het gebruikt deze informatie om de superklasse te bepalen die de methodeaanroep moet delegeren. Het doet dit door de klassenhiërarchie en de MRO te onderzoeken.
- Roep de methode aan op de superklasse: Zodra de superklasse is bepaald, super() Hiermee kunt u de methoden ervan aanroepen alsof u ze rechtstreeks vanuit de subklasse aanroept. Hierdoor kunt u methoden uitbreiden of overschrijven terwijl u nog steeds de oorspronkelijke implementatie van de superklasse gebruikt.
Super() gebruiken in een klassenconstructor
Gebruik makend van super() in een klassenconstructor is gebruikelijk, omdat u vaak algemene kenmerken in de bovenliggende klasse en meer specifieke kenmerken in de onderliggende klasse wilt initialiseren.
Om dit aan te tonen, definieer een Python-klasse, Vader, welke een Zoon klasse erft van:
classFather:
def__init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_nameclassSon(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 = hobbydefget_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())
Binnen in de Zoon constructor, de oproep naar super().init() doet een beroep op de Vader klasseconstructor, die deze doorgeeft Voornaam En achternaam als parameters. Dit zorgt ervoor dat de Vader class kan de naamattributen nog steeds correct instellen, zelfs op a Zoon voorwerp.
Als u niet belt super() in een klassenconstructor zal de constructor van de bovenliggende klasse niet worden uitgevoerd. Dit kan tot onbedoelde gevolgen leiden, zoals ontbrekende attribuutinitialisaties of een onvolledige instelling van de status van de bovenliggende klasse:
...
classSon(Father):
def__init__(self, first_name, last_name, age, hobby):
self.age = age
self.hobby = hobby
...
Als u nu probeert de informatie verkrijgen methode, zal het een AttribuutFout omdat de zelf.voornaam En zelf.achternaam attributen zijn niet geïnitialiseerd.
Super() gebruiken in klassenmethoden
Je kunt gebruiken super() in andere methoden, afgezien van constructors, op precies dezelfde manier. Hiermee kunt u het gedrag van de methode van de superklasse uitbreiden of overschrijven.
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 Zoon klasse erft van de Vader en heeft zijn spreken methode. De spreken werkwijze van de Zoon klasse gebruikt super().spreek() om te bellen spreken werkwijze van de Vader klas. Hierdoor kan het bericht van de bovenliggende klasse worden opgenomen en tegelijkertijd worden uitgebreid met een bericht dat specifiek is voor de onderliggende klasse.
Kan niet worden gebruikt super() in een methode die een andere overschrijft, betekent dit dat de functionaliteit die aanwezig is in de bovenliggende klassemethode geen effect heeft. Dit resulteert in een volledige vervanging van het methodegedrag, wat kan leiden tot gedrag dat u niet bedoelde.
Begrijpen Methode Resolutie Volgorde
Method Resolution Order (MRO) is de volgorde waarin Python voorouderklassen doorzoekt wanneer u een methode of attribuut opent. MRO helpt Python te bepalen welke methode moet worden aangeroepen als er meerdere overervingshiërarchieën bestaan.
classNigeria():
defculture(self):
print("Nigeria's culture")
classAfrica():
defculture(self):
print("Africa's culture")
Dit is wat er gebeurt als u een exemplaar van de Lagos klas en bel de cultuur methode:
- Python begint met het zoeken naar de cultuur methode in de Lagos klasse zelf. Als het deze vindt, roept het de methode aan. Als dit niet het geval is, gaat het verder met stap twee.
- Als het de cultuur methode in de Lagos class, kijkt Python naar de basisklassen in de volgorde waarin ze in de klassendefinitie voorkomen. In dit geval, Lagos erft eerst van Afrika en dan van Nigeria. Python zal dus zoeken naar de cultuur methode in Afrika Eerst.
- Als het de cultuur methode in de Afrika class, Python zal dan kijken in de Nigeria klas. Dit gedrag gaat door totdat het einde van de hiërarchie wordt bereikt en er een fout optreedt als de methode in geen van de superklassen kan worden gevonden.
De uitvoer toont de methode-resolutievolgorde van Lagos, beginnend van links naar rechts.
Veelvoorkomende valkuilen en beste praktijken
Bij het werken met super(), zijn er enkele veelvoorkomende valkuilen die u moet vermijden.
- Houd rekening met de Method Resolution Order, vooral in scenario's met meerdere overerving. Als u complexe meervoudige overerving moet gebruiken, moet u bekend zijn met de C3 Linearisatie-algoritme die Python gebruikt om MRO te bepalen.
- Vermijd circulaire afhankelijkheden in uw klassenhiërarchie, die tot onvoorspelbaar gedrag kunnen leiden.
- Documenteer uw code duidelijk, vooral bij gebruik super() in complexe klassenhiërarchieën, om het begrijpelijker te maken voor andere ontwikkelaars.
Gebruik super() op de juiste manier
Python's super() functie is een krachtige functie als u werkt met overerving en methode-overschrijving. Begrijpen hoe super() werkt en als u best practices volgt, kunt u beter onderhoudbare en efficiëntere code in uw Python-projecten maken.