2016-07-15 95 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