2012-08-06 5 views
8

La documentazione per functools.partial dice che è "più o meno equivalente a":functools.partial attuazione che antepone argomenti aggiuntivi

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 

Se avessi voluto implementare una versione che antepone gli argomenti aggiuntivi, sembra come dovrei solo cambiare la linea indicata.

Ci sono altre caratteristiche/trucchi che dovrei essere preoccupato solo copiando questo codice?

risposta

6

Guardando il codice sorgente per _functoolsmodule.c, non penso ci sia molto di cui preoccuparsi.

L'implementazione del modulo di partial maniglie decapaggio e repr, ma tutto il resto sembra che funziona come nella documentazione quindi presumibilmente la ragione per cui è implementato in C è solo per l'efficienza. C'è anche il fatto che si tratta di un tipo piuttosto che di una chiusura di funzione.

Nota, tuttavia, che nell'esempio di documentazione, func, args e keywords sono puramente estetici; non sono sovrascrivibili come lo sono con le istanze effettive functools.partial. Un'alternativa potrebbe essere quella di creare una sottoclasse functools.partial:

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

Non avevo pensato di creare una sottoclasse del costruito. – Dave

+0

Questo è grande, ma penso che dovrebbe leggere: classe rpartial (parziale): def __call __ (self, * args, ** kwargs): kw = self.keywords.copy() kw.update (kwargs) return self.func (* (args + self.args), ** kw) – ishmael

+0

@ishmael grazie, corretto. – ecatmur

0

Un trabocchetto è come il vostro cessione parziale sarebbe gestire argomenti arbitrari, come nel seguente esempio:

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

Ora applicare parzialmente f agli argomenti 1 e 2:

g = partial(f, 1, 2) 

Cos'è il valore del parametro b in g? È 1 o è ancora in attesa di un valore? Del resto, qual è il valore di a? In altre parole, quanti, se non nessuno, degli argomenti forniti dovrebbero essere trattati come argomenti aggiuntivi.

+0

Questo è un buon commento, ma mi piacerebbe dichiarare lo synatax per indicare 'g() == f (1,2); g (x) == f (x, 1,2); g (x, y) == f (x, y, 1,2) 'e così via. Che può essere strano, ma è sistematico. – Dave