2017-09-14 7 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 

Ich verstehe, dass *args in # 1 verwendet wird, da es eine Funktionsdeklaration ist. Aber warum ist es notwendig, *args in # 2 zu schreiben, auch wenn es keine Funktionsdeklaration ist?Warum brauchen wir `* args` im Dekorateur?

+1

Sie bündeln die Positionsargumente in das Tupel von Argumenten und entbündeln sie dann wieder in separate Argumente, wenn Sie die Wrapped-Funktion aufrufen. – jonrsharpe

Antwort

1

Wenn in Funktionsdeklaration verwendet, *args Positionsargumente in Tupels drehen:

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

Wenn in Funktionsaufruf verwendet, *args Tupels in Positionsargumente erweitert:

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

Dies ist zwei entgegengesetzte Prozesse, Wenn sie so kombiniert werden, können beliebig viele Argumente an die dekorierte Funktion übergeben werden.

@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