使用装饰器设置参数与嵌套函数

Setting parameters with decorators vs nested functions

我需要多次调用一个多参数函数,而除一个参数外的所有参数都是固定的。我正在考虑使用装饰器:

# 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

但我对使用这种方法犹豫不决,因为在我的实际实现中,包装函数非常复杂。我的直觉是它应该有一个独立的定义。

如果这涉及到意见领域,请原谅我,但是任何一种方法都被认为是更好的设计 and/or 更 Pythonic 吗?我应该考虑其他方法吗?

functools.partial 在这种情况下应该能很好地工作:

from functools import partial

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

adder_2 = partial(adder, 2)

adder_2(5)

它的文档字符串:

partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords.

-- 所以,你也可以设置关键字参数。

PS

遗憾的是,内置的 sum 不适合这种情况:它对一个可迭代对象求和(实际上,sum(iterable[, start]) -> value),所以 partial(sum, 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