【问题标题】:Setting parameters with decorators vs nested functions使用装饰器与嵌套函数设置参数
【发布时间】:2016-11-18 01:36:02
【问题描述】:

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

# 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

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

如果这冒险进入意见领域,请原谅我,但是这两种方法是否被认为是更好的设计和/或更 Pythonic?我应该考虑其他一些方法吗?

【问题讨论】:

    标签: python decorator python-decorators


    【解决方案1】:

    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) - 部分应用的新函数 给定的参数和关键字。

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

    PS

    遗憾的是,内置的sum 不适合这种情况:它对一个可迭代对象求和(实际上是sum(iterable[, start]) -> value),所以partial(sum, 2) 不起作用。

    【讨论】:

    • 这很干净。谢谢。
    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-11
      • 1970-01-01
      • 2020-01-15
      • 2014-05-01
      • 1970-01-01
      • 2016-07-27
      • 2021-10-01
      • 2016-01-30
      相关资源
      最近更新 更多