2016-07-15 9 views
2

Ich muss eine Multi-Parameter-Funktion viele Male aufrufen, während alle außer einem Parameter fest ist. Ich dachte an Dekorateure mit:Einstellen von Parametern mit Decorators vs verschachtelte Funktionen

# V1 - with @decorator 
def dec_adder(num): 
    def wrap(fun): 
     def wrapped_fun(n1): 
      return fun(n1, second_num=num) 
     return wrapped_fun 
    return wrap 

@dec_adder(2) 
def adder(first_num, second_num): 
    return first_num + second_num 

print adder(5) 
>>> 7 

Aber das scheint verwirrend, da es eine 2-Parameter-Funktion aufrufen, adder mit nur einem Argument zu sein scheint.

Ein weiterer Ansatz ist es, eine verschachtelte Funktionsdefinition zu verwenden, die lokalen Variablen aus der übergeordneten Funktion verwendet:

# V2 - without @decorator 
def add_wrapper(num): 
    def wrapped_adder(num_2): 
     return num + num_2 
    return wrapped_adder 

adder = add_wrapper(2) 
print adder(5) 
>>> 7 

Aber ich zögere in meiner tatsächlichen Implementierung, da diesen Ansatz zu verwenden, die verpackte Funktion sehr komplex ist. Mein Instinkt ist, dass es eine eigenständige Definition haben sollte.

Verzeihen Sie mir, wenn dies in den Bereich der Meinung wagt, aber ist entweder Ansatz als besseres Design und/oder mehr Pythonic? Gibt es einen anderen Ansatz, den ich berücksichtigen sollte?

Antwort

2

functools.partial sollte schön in diesem Fall arbeiten:

from functools import partial 

def adder(n1, n2): 
    return n1 + n2 

adder_2 = partial(adder, 2) 

adder_2(5) 

Sein docstring:

Teil (func, * args, ** Schlüsselwörter) - Neue Funktion mit teilweise Anwendung der gegebenen Argumente und Schlüsselwörter.

- Sie können also auch Schlüsselwortargumente festlegen.

PS

Leider die eingebaut in sum nicht diesem Fall passen: Arbeit sind Beträge über eine iterable (in der Tat, sum(iterable[, start]) -> value), so hat partial(sum, 2) nicht.

+0

Das ist schön und sauber. Vielen Dank. – andrew

2

Eine andere mögliche Lösung - können Sie functools und parametrisierte Dekorateur verwenden:

from functools import wraps 

def decorator(num): 
    def decor(f): 
     @wraps(f) 
     def wrapper(n,*args,**kwargs): 
      return f(n+num,*args,**kwargs) 
     return wrapper 
    return decor 


@decorator(num=2) # number to add to the parameter 
def test(n,*args,**kwargs): 
    print n 


test(10) # base amount - prints 12 
Verwandte Themen