Die Funktion partial wurde in der Standardbibliothek von Python (Modul functools) eingeführt, beginnend mit Python 2.5, um das Currying-Muster und die partielle Anwendung von Argumenten auf eine Funktion zu implementieren. partialmethod wurde mit Python 3.4 für eine ähnliche Anwendung in Klassenmethoden eingeführt.
In vielen realen Projekten besteht oft die Notwendigkeit, einen Teil der Argumente einer Funktion zu fixieren, um eine neue Funktion mit "festgelegten" Werten einiger Argumente zu erhalten. Dies ist nützlich für Callbacks, Argumentübergabemuster oder zur Verbesserung der Lesbarkeit des Codes, insbesondere in der funktionalen Programmierung und bei der Verwendung von APIs, die einen bestimmten Stil von Funktionen erwarten.
Die Funktion partial gibt ein neues Funktionsobjekt zurück, in das einige der übergebenen Argumente oder Schlüsselargumente "hart" integriert (fixiert) sind. partialmethod implementiert denselben Ansatz für Klassenmethoden und unterstützt korrekt die Mechanik der Übergabe von self/cls.
Codebeispiel:
from functools import partial, partialmethod def power(base, exponent): return base ** exponent # Fixieren der Potenz = 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
Wesentliche Merkmale:
Kann partial für Klassenmethoden verwendet werden, um eine ähnliche Funktion wie partialmethod zu erhalten?
Nein, partial verarbeitet self/cls nicht korrekt, wenn es auf eine Klassenmethode angewendet wird, funktioniert es nicht wie erwartet: self wird nicht automatisch übergeben.
class C: def m(self, x, y): return x + y wrong = partial(m, y=2) # Falsch!
Bei Aufruf von c.wrong(5) wird ein TypeError auftreten, weil self nicht automatisch übergeben wird.
Ist das durch partial erzeugte Objekt eine Funktion?
Ja, das Ergebnis von partial ist ein Objekt, das sich wie eine Funktion verhält, den Aufruf, den Namen, die Dokstring usw. unterstützt, aber es ist keine gewöhnliche Funktion, sondern ein Objekt der Klasse partial, das das call-Protokoll implementiert.
from functools import partial f = partial(pow, 2) print(type(f)) # <class 'functools.partial'>
Funktioniert partial mit Standardargumenten von Funktionen?
Ja, partial kann die Standardwerte in der internen Funktion "überschreiben"; wenn Argumente an partial übergeben werden, haben sie Vorrang vor den Standardwerten in der Funktion selbst. Es ist jedoch wichtig, Werte nicht zu duplizieren, da dies zu einem Fehler führt.
Ein Entwickler verwendet partial für eine Klassenmethode anstelle von partialmethod:
class MyClass: def f(self, x, y): ... squared = partial(f, y=2) ... obj = MyClass() obj.squared(5) # TypeError: missing 1 required positional argument: 'self'
Vorteile:
Nachteile:
Stattdessen wird partialmethod verwendet:
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
Vorteile:
Nachteile: