2017-09-14 55 views
-2
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 

我知道*args在#1中使用,因为它是一个函数声明。但为什么有必要在#2中编写*args,即使它不是函数声明?为什么我们需要装饰器中的`* args`?

+1

将位置参数捆绑到args的元组中,然后在调用包装函数时将它们分开放回单独的参数中。 – jonrsharpe

回答

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