为什么我们在装饰器中需要`* args`?

时间:2017-09-14 08:11:58

标签: python decorator args

def pass_thru(func_to_decorate):
    def new_func(*args, **kwargs):  #1
        print("Function has been decorated.  Congratulations.")
        # Do whatever else you want here
        return func_to_decorate(*args, **kwargs)  #2
    return new_func


def print_args(*args):
    for arg in args:
        print(arg)


a = pass_thru(print_args)
a(1,2,3)

>> Function has been decorated.  Congratulations.
1
2
3

我理解{1}用于#1,因为它是一个函数声明。但是为什么有必要在#2中编写*args,即使它不是函数声明?

1 个答案:

答案 0 :(得分:1)

在函数声明中使用时,*args将位置参数转换为元组:

def foo(a, *args):
    pass
foo(1, 2, 3)    #  a = 1, args = (2, 3)

在函数调用中使用时,*args将元组扩展为位置参数:

def bar(a, b, c):
    pass
args = (2, 3)
foo(1, *args)   # a = 1, b = 2, c = 3

这是两个相反的过程,因此组合它们允许将任意数量的参数传递给修饰函数。

@pass_thru
def foo(a, b):
    pass
@pass_thru
def bar(a, b, c):
    pass

foo(1, 2)     # -> args = (1, 2) -> a = 1, b = 2
bar(1, 2, 3)  # -> args = (1, 2, 3) -> a = 1, b = 2, c = 3