De functie super() gebruiken in Python-klassen
Belangrijkste resultaten
Pythons gebruik van de functie super()
vergemakkelijkt het aanroepen van methoden binnen een subklasse door toegang te krijgen tot de superklasse, waardoor het proces van het implementeren van overerving en methode-overrides op een elegante manier wordt verbeterd.
De functie super()
heeft een belangrijk verband met de Method Resolution Order (MRO) in Python, die de volgorde bepaalt waarin voorouderlijke klassen worden onderzocht op methoden en eigenschappen tijdens methoderesolutie.
Het gebruik van super()
binnen de constructor van een klasse is een gebruikelijke aanpak voor het vaststellen van gedeelde kenmerken in de bovenliggende klasse, terwijl meer specifieke eigenschappen worden gedefinieerd in de onderliggende klasse. Het niet implementeren van super()
kan resulteren in ongewenste resultaten, waaronder het niet initialiseren van eigenschappen.
Een van de fundamentele aspecten van de programmeertaal Python is het Objectgeoriënteerd Programmeren (OOP) paradigma, waarmee modellen kunnen worden gemaakt die levensechte objecten en hun onderlinge verbindingen op een gestructureerde manier weergeven.
In de context van programmeren met Python is het gebruikelijk om overerving te gebruiken om kenmerken of functies van de bovenliggende entiteit van een klasse te wijzigen of te vervangen. De taal biedt een handig mechanisme dat bekend staat als de “super()” functie, die het mogelijk maakt om de methoden van de hogere klasse aan te roepen vanuit de ondergeschikte klasse.
Wat is super() en waarom heb je het nodig?
Overerven van een bestaande klasse maakt het mogelijk om een nieuwe klasse te maken met gelijkaardige attributen en gedrag via het proces van overerving. Bovendien kan men ervoor kiezen om specifieke methodes binnen de subklasse te overschrijven om een eigen unieke implementatie te voorzien. Hoewel deze nieuwe functionaliteit wenselijk kan zijn, zijn er gevallen waarin het de voorkeur verdient om zowel de originele als de nieuw geïmplementeerde functionaliteit tegelijkertijd te gebruiken. In zulke gevallen maakt het gebruik van de functie super()
integratie van beide sets van mogelijkheden in de subklasse mogelijk.
Om de eigenschappen en methoden van een superklasse in objectgeoriënteerd programmeren te gebruiken, kan men de functie super()
gebruiken. Deze functie speelt een cruciale rol omdat het de implementatie van overerving en methode-overschrijving vergemakkelijkt, wat fundamentele concepten zijn in object-georiënteerd programmeren.
Hoe werkt super()?
Intern is het gedrag van de super()
functie verweven met het concept van de Method Resolution Order (MRO), een mechanisme dat wordt bepaald door het C3 linearisatie algoritme in Python.
Hier wordt uitgelegd hoe super() werkt:
Wanneer je super()
aanroept binnen een methode van een subklasse in Python, identificeert de taal automatisch zowel de huidige klasse, die de aanroepende methode bevat, als de instantie van die klasse die wordt vertegenwoordigd door self
.
⭐ Bepaal de superklasse : super() neemt twee argumenten aan â€" de huidige klasse en de instantie â€" die je niet expliciet hoeft door te geven. Het gebruikt deze informatie om de superklasse te bepalen om de methodeaanroep te delegeren. Het doet dit door de klassenhiërarchie en de MRO te onderzoeken.
Zodra een superklasse geïdentificeerd is, staat de functie super()
het aanroepen van zijn methodes toe alsof ze rechtstreeks vanuit de subklasse worden aangeroepen. Deze mogelijkheid vergemakkelijkt zowel het uitbreiden als het overschrijven van methodes van de superklasse, terwijl de oorspronkelijke implementatie van de superklasse gebruikt wordt.
Super() gebruiken in een klasseconstructor
Het gebruik van de super() methode opnemen in de constructors van klassen is een veelgebruikte aanpak, omdat het de initialisatie van gedeelde eigenschappen tussen broer-zus klassen mogelijk maakt, terwijl het unieke kenmerken in elke individuele nakomeling toestaat.
Om het concept van overerving in objectgeoriënteerd programmeren met Python te illustreren, kunnen we een “Vader” klasse maken die dient als basisklasse voor een andere klasse genaamd “Zoon”. De “Zoon” klasse zal eigenschappen en methodes erven van zijn bovenliggende klasse, de “Vader”, en zo aantonen hoe overerving hergebruik van code en modulariteit mogelijk maakt.
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())
Binnen de grenzen van de constructor van de klasse Son
wordt de verplichting om de auspiciën van zijn ouderklasse aan te roepen uitgevoerd door de wonderbaarlijke handeling van het oproepen van de functie super()
. Deze cruciale actie activeert het opstarten van de vaderlijke Father
klasseconstructor, waarbij twee gewaardeerde, belangrijke kwalificaties worden aangeboden in de vorm van de first_name
en last_name
variabelen. Op deze manier behoudt de klasse Vader
de mogelijkheid om deze nominale aanduidingen nauwkeurig te verkrijgen en toe te wijzen, ondanks de instantiatie van een Zoon
.
In gevallen waar de super()
methode niet wordt aangeroepen binnen de
...
class Son(Father):
def __init__(self, first_name, last_name, age, hobby):
self.age = age
self.hobby = hobby
...
Als je probeert om de get_info
methode op dit moment aan te roepen, zal dit resulteren in het genereren van een AttributeError
, aangezien de self.first_name
en self.last_name
attributen nog moeten worden geïnitialiseerd.
Super() gebruiken in klassemethoden
Men kan het gebruik van de super() functie niet alleen gebruiken binnen de grenzen van constructorprocedures, maar ook in een diverse reeks methoden om de functionaliteit van de methodologische benadering van de hoofdklasse te vergroten of te vervangen.
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)
De Son
klasse in Python is ontworpen om eigenschappen en methoden te erven van de bovenliggende of Father
klasse, inclusief de speak()
methode. Door gebruik te maken van de super().speak()
functie binnen de speak()
methode van de Son
klasse, kan het effectief een beroep doen op de originele speak()
methode van de Father
klasse, terwijl het ook alle extra informatie of berichten bevat die uniek zijn voor de Son
klasse.
In gevallen waarin een methode een andere overschrijft zonder gebruik te maken van de super()
functie, wordt de bedoelde functionaliteit van de bovenliggende klasse niet uitgevoerd. Dit kan resulteren in onbedoeld gedrag doordat een geheel nieuwe en aparte methode de oorspronkelijke functionaliteit vervangt.
Method Resolution Order
De Method Resolution Order (MRO) verwijst naar de hiërarchie van voorrang die bepaalt in welke volgorde Python zal zoeken naar methodes en attributen bij complexe klassenstructuren met meervoudige overerving. Dit mechanisme zorgt ervoor dat de juiste methode wordt aangeroepen op basis van de beschikbare opties binnen de respectievelijke bovenliggende klassen, waardoor mogelijke ambiguïteiten als gevolg van overlappende definities worden opgelost.
class Nigeria():
def culture(self):
print("Nigeria's culture")
class Africa():
def culture(self):
print("Africa's culture")
Wanneer de Lagos klasse wordt geïnstantieerd en de cultuurmethode wordt aangeroepen, vinden er een aantal gebeurtenissen plaats die bijdragen aan de algehele functionaliteit van het object. De uitvoering van de code doorloopt verschillende stadia waarbij gegevens worden gemanipuleerd, informatie van externe bronnen wordt opgehaald en verschillende algoritmen worden toegepast om culturele aspecten te analyseren op basis van invoerparameters die door de gebruiker zijn opgegeven of standaardwaarden die in de constructor zijn ingesteld. Het eindresultaat is een uitgebreide beoordeling van de culturele kenmerken van de gespecificeerde stad, zoals weergegeven door de Lagos-klasse.
Python zoekt eerst naar de culture
methode binnen de Lagos
klasse zelf. Als deze methode wordt gevonden en beschikbaar is, wordt deze door het algoritme aangeroepen. Als een dergelijke methode echter niet bestaat of niet toegankelijk is, gaat het proces door naar de volgende fase.
Als de klasse Lagos
geen methode culture()
heeft, zoekt Python naar de methode in de basisklassen van de klassenhiërarchie, te beginnen met de klassen die na de dubbele punt staan ( :
) en die geërfd zijn door de klasse Lagos
. In dit voorbeeld wordt de klasse Lagos
gedefinieerd om eerst te erven van de klasse Africa
en daarna van de klasse Nigeria
. Daarom, als de klasse Lagos
geen eigen implementatie van de methode culture()
bevat, zal Python proberen de methode te lokaliseren in de klasse Africa
voordat de klasse Nigeria
wordt doorzocht.
Het zoeken naar een cultuurspecifieke methode binnen een gegeven klassenhiërarchie gaat door een reeks geneste klassen, waarbij elke volgende klasse wordt onderzocht voor het geval de gewenste methode daarin wordt gevonden. In het geval dat de methode niet wordt ontdekt op het eerste onderzoeksniveau, namelijk de Afrikaanse klasse, verlegt Python zijn focus naar de volgende hoogste klasse in de hiërarchische structuur, die in dit geval overeenkomt met de Nigeriaanse klasse. Dit proces herhaalt zich naarmate men afdaalt in de klassenboom, van meest algemeen naar minst specifiek, totdat de gezochte methode in geen enkele van de aangetroffen superklassen kan worden gevonden. Op dat moment wordt er een uitzondering gemaakt om aan te geven dat de zoekopdracht niet succesvol was.
De methode resolutie volgorde (MRO) voor Lagos wordt lineair weergegeven, beginnend vanaf links en oplopend naar rechts.
Veelvoorkomende valkuilen en best practices
Bij het gebruik van de functie super()
is het belangrijk om bewust te zijn van bepaalde mogelijke misstappen om te zorgen voor een soepele en effectieve ervaring.
⭐ Let op de volgorde van de methoderesolutie, vooral in scenario’s met meervoudige overerving. Als u complexe meervoudige overerving moet gebruiken, moet u bekend zijn met het C3 Linearisatie algoritme dat Python gebruikt om MRO te bepalen.
Circulaire afhankelijkheden binnen een klassehiërarchie moeten vermeden worden omdat ze kunnen leiden tot grillig en moeilijk te anticiperen gedrag.
Bij het werken met ingewikkelde klassehiërarchieën waarbij de functie super()
gebruikt wordt, is het cruciaal om een duidelijke en goed gedocumenteerde codebase te onderhouden. Dit zorgt niet alleen voor een goede functionaliteit, maar bevordert ook het begrip bij andere ontwikkelaars die in de toekomst mogelijk aan de code moeten werken of deze moeten aanpassen. Door beknopt maar informatief commentaar te geven, kunt u de leesbaarheid en onderhoudbaarheid van uw project verbeteren, de samenwerking vergemakkelijken en mogelijke fouten of verwarring verminderen.
Super() op de juiste manier gebruiken
Python’s gebruik van de super()
functie is een onmisbaar aspect van zijn object-georiënteerd programmeerparadigma, vooral met betrekking tot het vergemakkelijken van overerving en methode overschrijvingen. Het begrijpen van de fijne kneepjes van deze functionele entiteit en het naleven van vastgestelde best practices zorgt voor de ontwikkeling van duurzamere en vindingrijkere softwaretoepassingen binnen het Python ecosysteem.