De functie partial is geïntroduceerd in de standaard bibliotheek van Python (functies in het module functools) vanaf Python 2.5, om het patroon van currying en gedeeltelijke argumenttoepassing op functies te implementeren. partialmethod verscheen met Python 3.4 voor een vergelijkbare toepassing in klassenmethoden.
Vaak vereist de praktijk in echte projecten het vastzetten van een deel van de argumenten van een functie, om een nieuwe functie te krijgen met "opgeslagen" waarden voor bepaalde argumenten. Dit is handig voor callbacks, argumentoverdrachtsjablonen, of voor het verbeteren van de leesbaarheid van de code, vooral in functioneel programmeren en bij het gebruik van API's die een bepaalde functionele stijl verwachten.
De functie partial retourneert een nieuw functie-object, waarin bepaalde doorgegeven argumenten of sleutelargumenten "hardcoded" (vastgelegd) zijn. partialmethod implementeert dezelfde aanpak voor klassenmethoden, waarbij de self/cls-mechaniek correct wordt ondersteund.
Voorbeeldcode:
from functools import partial, partialmethod def power(base, exponent): return base ** exponent # Vastzetten van exponent = 2 square = partial(power, exponent=2) print(square(5)) # 25 class Math: def power(self, base, exponent): return base ** exponent square = partialmethod(power, exponent=2) m = Math() print(m.square(5)) # 25
Belangrijke kenmerken:
Kan partial worden gebruikt voor klassenmethoden om een equivalente partialmethod te krijgen?
Nee, partial behandelt self/cls niet correct, het werkt niet zoals verwacht wanneer het op een klassenmethode wordt toegepast: self wordt niet automatisch ingevuld.
class C: def m(self, x, y): return x + y wrong = partial(m, y=2) # Fout!
Bij het aanroepen van c.wrong(5) zal een TypeError optreden, omdat self niet automatisch wordt doorgegeven.
Is het object dat via partial is gemaakt een functie?
Ja, het resultaat van partial is een object dat zich gedraagt als een functie, ondersteunt aanroepen, naam, docstring, enz., maar dit is geen gewone functie, dit is een object van de partial-klasse die het call-protocol implementeert.
from functools import partial f = partial(pow, 2) print(type(f)) # <class 'functools.partial'>
Werkt partial met standaardargumenten van functies?
Ja, partial kan de standaardwaarden in de interne functie "overschrijven"; als argumenten aan partial worden doorgegeven, hebben deze voorrang boven de standaardwaarden in de functie zelf. Het is echter belangrijk om geen waarden te dupliceren, anders zal er een fout optreden.
Een ontwikkelaar gebruikt partial voor een klassenmethode in plaats van partialmethod:
class MyClass: def f(self, x, y): ... squared = partial(f, y=2) ... obj = MyClass() obj.squared(5) # TypeError: ontbreekt 1 vereist positioneel argument: 'self'
Voordelen:
Nadelen:
In plaats daarvan wordt partialmethod gebruikt:
from functools import partialmethod class MyClass: def f(self, x, y): return x + y squared = partialmethod(f, y=2) obj = MyClass() print(obj.squared(5)) # 7
Voordelen:
Nadelen: