2016-07-15 151 views
2

我需要調用一個多參數的功能很多次,而所有,但一個參數是固定的。我在考慮使用裝飾的:設置參數

# 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 

但因爲它似乎調用2參數功能,adder只有一個說法,這似乎令人困惑。

另一種方法是使用使用本地變量從父函數嵌套函數定義:

# 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 

但我毫不猶豫地使用這種方法,因爲在我的實際執行的包裹功能是非常複雜的。我的直覺是它應該有一個獨立的定義。

原諒我,如果這個企業到輿論的境界,但兩種方法認爲是更好的設計和/或更Python?我應該考慮一些其他方法嗎?

回答

2

functools.partial應該更好地工作,在這種情況下:

from functools import partial 

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

adder_2 = partial(adder, 2) 

adder_2(5) 

其文檔字符串:

部分(FUNC,* ARGS,**關鍵字) - 新功能與給定的部分應用程序 參數和關鍵字。

- 所以,你可以設置關鍵字參數也是如此。

PS

可悲的是,內置sum不適合這種情況:它總結了一個可迭代(事實上,sum(iterable[, start]) -> value),所以partial(sum, 2)不起作用。

+0

這是非常乾淨的。謝謝。 – andrew

2

另一種可能的解決方案 - 您可以使用functools和參數化的裝飾:

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