Functie-overloading in Python begrijpen
Functie-overloading is een functie in sommige programmeertalen waarmee je variaties van dezelfde functie kunt definiëren. Elke variant heeft dezelfde naam, maar verschillende implementaties, met unieke functiehandtekeningen.
Deze methode maakt het mogelijk om verschillende acties uit te voeren die afhankelijk zijn van de aard en de hoeveelheid van de parameters die aan een functie worden doorgegeven, waardoor een grotere flexibiliteit bij het programmeren mogelijk wordt.
Python verschilt van programmeertalen als het Nederlands en Java doordat het inherent geen functie-overload ondersteunt. Men kan deze functionaliteit echter op alternatieve manieren emuleren.
Hoe gaat Python om met functieverzwaring?
In Python kan een functie meerdere keren gedefinieerd worden met verschillende parameterspecificaties en/of datatypes. Desondanks zal Python bij het aanroepen van de functie alleen het laatste exemplaar van de definitie erkennen. Hieronder wordt een voorbeeld gegeven:
def arithmetics(a, b):
return a - b
def arithmetics(a, b, c, d):
return a \\+ b - c * d
print(arithmetics(1, 2, 3, 5)) # returns -12
print(arithmetics(1, 2)) # returns missing positional arguments error
Object-georiënteerde programmeertalen zoals Java bevatten vaak mechanismen voor functie- en methode-overloading. In essentie zijn methoden functies die zijn afgebakend binnen de context van een klasse.
In het bovenstaande codefragment zal de Python interpreter alleen de laatst gedeclareerde definitie van de arithmetic() functie erkennen wanneer hij deze probeert aan te roepen binnen een project. Als iemand de functie probeert aan te roepen met twee parameters die overeenkomen met de oorspronkelijke declaratie, zal er een uitzondering worden gemaakt die aangeeft dat deze argument(en) ontbreken en vereist zijn voor uitvoering.
Er treedt geen functiefout op wanneer vier parameters worden opgegeven tijdens het aanroepen, wat aangeeft dat de functie is vervangen door de meest recente versie in het geheugen. Dit duidt echter niet op method overloading en vereist een andere aanpak voor het oplossen.
Python ondersteunt inherent geen functie-overload; men kan echter bepaalde technieken in hun code gebruiken om deze functionaliteit te emuleren.
Methode 1: Optionele parameters of standaardargumenten gebruiken
Je kunt overloading bereiken door functies met standaardparameters te implementeren. Een demonstratief voorbeeld is als volgt:
def arithmetics(a, b=0, c=0):
"""
Arguments:
a: The first number.
b: The second number (optional).
c: The third number (optional).
"""
return a - b \\+ c
De gegeven functie bevat in totaal drie invoervariabelen, maar twee daarvan hebben vooraf gedefinieerde waarden. Hierdoor kan de functie worden aangeroepen met een array van één tot drie argumentatieve elementen.
print(arithmetics(1)) # returns 1
print(arithmetics(2, 5)) # returns -3
print(arithmetics(10, 3, 4)) # returns 11
Hoewel deze methode verschillende mogelijkheden biedt om de functie aan te roepen, blijkt het uiteindelijk een onhoudbare oplossing vanwege verschillende inherente beperkingen.
Het argument dat wordt doorgegeven moet van het type geheel getal of float zijn.
Er lijkt geen waarneembare variatie te zijn in de functionaliteit van deze specifieke functie. Bijgevolg blijft het onmogelijk om taken uit te voeren zoals het berekenen van de oppervlakte van een gegeven vorm of het afdrukken van de tekst “Hello World”.
Methode 2: Variabele argumenten gebruiken
Om variabele argumentoverload in Python te gebruiken, is het essentieel om de parameter “args” op te nemen tijdens het definiëren van een functie. Dit attribuut maakt het mogelijk om meerdere positionele argumenten door te geven tijdens het aanroepen van de functie. Hieronder staat een voorbeelddemonstratie:
def arithmetics(a, *args):
"""
Arguments:
a: The first number.
*args: A variable number of arguments (optional).
"""
args_sum = 0
for num in args:
args_sum *= num
return a - args_sum
print(arithmetics(1)) # returns 1
print(arithmetics(2, 5)) # returns 2
print(arithmetics(10, 3, 4, 2, 4, 6)) # returns 10
De bovenstaande functie vereist twee parameters; een verplichte parameter aangeduid als “a” en een optionele parameter aangeduid als “args”, waardoor het mogelijk is om elk gewenst aantal extra argumenten op te nemen.
Ondanks de mogelijkheid om een groot aantal invoergegevens te accepteren, is deze functie beperkt in zijn vermogen om rekenkundige bewerkingen uit te voeren die verder gaan dan eenvoudige vermenigvuldiging, omdat het alleen het vermenigvuldigingsproces toepast op de variabelen die worden vertegenwoordigd door het Args
sleutelwoord.
Om een reeks acties uit te voeren in een programmatische context, is het vaak nodig om voorwaardelijke verklaringen in de code op te nemen. Echter, naarmate het aantal voorwaarden toeneemt, neemt ook de complexiteit van de programmeertaak toe.
Methode 3: De Multiple Dispatch Decorator gebruiken
De Multiple Dispatch Decorator is een Python-bibliotheek die het mogelijk maakt om verschillende implementaties of instanties van een enkele functie te maken, afhankelijk van het type invoer dat het ontvangt. Door dit te doen, kan men identieke functies met verschillende gegevensstructuren maken en hun gedrag volledig veranderen.
Om de multi-method dispatch versiering te gebruiken, moet je je aan deze protocollen houden:
⭐ Installeer multipledispath in je Python-omgeving:
pip install multipledispatch
⭐ Versier je functie(s) met de @dispatch decorator. De @dispatch decorator is een Python decorator waarmee je meervoudige dispatch kunt implementeren. Het zal automatisch de juiste functie dispatchen op basis van de argumenten die je er aan doorgeeft. Je kunt de @dispatch decorator gebruiken door het volgende patroon te volgen:
from multipledispatch import dispatch
@dispatch(data type1, data type2, data typeX)
def your_function(a, b, c, x):
pass
# perform your operations here
Beschouw een scenario waarin we gebruikmaken van de decorator voor meervoudige dispatch om het concept van functieoverbelasting in de programmeertaal Python te vergemakkelijken:
from multipledispatch import dispatch
@dispatch(int, int)
def add(a, b):
"""
Arguments:
a: Any integer.
b: Any integer.
"""
return a \\+ b
@dispatch(int, list)
def add(a, b):
"""
Arguments:
a: Any integer.
b: Any Python list.
"""
b.append(a)
return b
# returns 3
print(add(1, 2))
# returns [2, 3, 4, 5, 'w', 'done', 1]
print(add(1, [2, 3, 4, 5, 'w', 'done']))
Het bovenstaande codesegment installeert twee afzonderlijke instanties van de functie add(), waarbij elke instantie verschillende parameters accepteert en verwerkt. Specifiek ontvangt en berekent één zo’n incarnatie de som van twee numerieke waarden die worden weergegeven als gehele gegevenstypen, en levert uiteindelijk het resulterende totaal in termen van het resultaat van een rekenkundige bewerking.
De volgende iteratie van deze bewerking omvat afwisselend de acceptatie van twee parameters: een geheel getal en een sequentiële verzameling. Vervolgens wordt de genoemde parameter toegevoegd aan het einde van de reeks en geretourneerd als de gewijzigde accumulatie.
Deze benadering van functie-overloading in Python geeft je veel flexibiliteit, vooral als je het gedrag van je methode moet veranderen. Je kunt meer te weten komen in de documentatie multiple dispatch .
De beste aanpak voor functieoverbelasting in Python
De selectie van een geschikte methode voor functieoverbelasting moet in overeenstemming zijn met de beoogde doelen. In gevallen waar het gewenste resultaat kan worden bereikt door gebruik te maken van standaard of variabele argumenten, kan het niet nodig zijn om de multi-dispatch decorator te gebruiken. Desalniettemin presenteert de laatste zich in de meeste gevallen als een efficiëntere en nauwkeurigere oplossing vanwege de mogelijkheid om verschillende argumenttypen te accommoderen met behoud van optimale prestaties.
De meegeleverde decorator biedt een elegante en veelzijdige benadering voor het implementeren van functie-overloading in de programmeertaal Python. Het maakt het mogelijk om verschillende implementaties van een enkele functie te maken, afhankelijk van de eigenschappen van de parameters.
Het gebruik van deze methode maakt het mogelijk om veelzijdige functies te ontwikkelen die een verscheidenheid aan parametertypes kunnen accommoderen, zonder dat er ingewikkelde voorwaardelijke verklaringen nodig zijn om deze aanpasbaarheid te bereiken.