2012-08-06 6 views
8

Die Dokumentation für functools.partial sagt, dass es „in etwa gleichwertig“ ist:Umsetzung functools.partial, die zusätzliche Argumente prepends

def partial(func, *args, **keywords): 
    def newfunc(*fargs, **fkeywords): 
     newkeywords = keywords.copy() 
     newkeywords.update(fkeywords) 
     return func(*(args + fargs), **newkeywords) # line to change 
    newfunc.func = func 
    newfunc.args = args 
    newfunc.keywords = keywords 
    return newfunc 

Wenn ich eine Version, dass wird vorangestellt die zusätzlichen Argumente umsetzen wollten, es scheint als müsste ich nur die angezeigte Linie ändern.

Gibt es noch andere Features/Fehler, über die ich mir beim Kopieren dieses Codes Sorgen machen sollte?

Antwort

6

Betrachtet man den Quellcode für _functoolsmodule.c, denke ich nicht, dass es viel zu sorgen gibt.

Das Modul Implementierung von partial Griffe Beizen und repr, aber alles sieht anders wie es in der Dokumentation funktioniert so vermutlich der Grund, es in C implementiert ist, ist nur für Effizienz. Es gibt auch die Tatsache, dass es sich um einen Typ handelt und nicht nur um einen Funktionsabschluss.

Beachten Sie jedoch, dass im Dokumentationsbeispiel func, args und keywords rein kosmetischer Natur sind; Sie sind nicht überschreibbar wie bei tatsächlichen functools.partial Instanzen. Eine Alternative wäre functools.partial Unterklasse:

class rpartial(partial): 
    def __call__(self, *args, **kwargs): 
     kw = self.keywords.copy() 
     kw.update(kwargs) 
     return self.func(*(args + self.args), **kwargs) 
+0

Hatte nicht daran gedacht, das eingebaute zu unterklassifizieren. – Dave

+0

Das ist großartig, aber ich denke, es sollte lauten: Klasse rpartial (teilweise): def __call __ (self, * args, ** kwargs): kw = self.keywords.copy() kw.update (kwargs) return self.func (* (args + self.args), ** kw) – ishmael

+0

@ishmael danke, behoben. – ecatmur

0

Ein Fallstrick ist, wie Sie Ihre Teil-Zuordnung beliebige Argumente behandeln würde, wie im folgenden Beispiel:

def f(a,b, *args): 
    pass 

Jetzt gelten teilweise f auf die Argumente 1 und 2:

g = partial(f, 1, 2) 

Was ist der Wert des Parameters b in g? Ist es 1, oder wartet es immer noch auf einen Wert? Was ist der Wert von a? Anders ausgedrückt: Wie viele der bereitgestellten Argumente sollten gegebenenfalls als zusätzliche Argumente behandelt werden.

+0

Dies ist ein guter Kommentar, aber ich würde die synatax erklären bedeuten 'g() == f (1,2); g (x) == f (x, 1,2); g (x, y) == f (x, y, 1,2) und so weiter. Das kann seltsam sein, ist aber systematisch. – Dave

Verwandte Themen