问题
I am learning decorator functions in python and I am wrapping my head around the @ syntax.
Here is a simple example of a decorator function which calls the relevant function twice.
def duplicator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
func(*args, **kwargs)
return wrapper
If I understand correctly, it appears that:
@duplicator
def print_hi():
print('We will do this twice')
Is equivalent to:
print_hi = duplicator(print_hi)
print_hi()
However, let's consider if I move to a more complex example. E.g. instead of calling the function twice, I want to call it a user-defined amount of times.
Using an example from here: https://realpython.com/primer-on-python-decorators/
def repeat(num_times):
def decorator_repeat(func):
@functools.wraps(func)
def wrapper_repeat(*args, **kwargs):
for _ in range(num_times):
value = func(*args, **kwargs)
return value
return wrapper_repeat
return decorator_repeat
I can call this via:
@repeat(num_times=4)
def print_hi(num_times):
print(f"We will do this {num_times} times")
However, this is most certainly not equivalent to:
print_hi = repeat(print_hi)
Because we have the extra argument of num_times
.
What am I misunderstanding? Is it equivalent to:
print_hi = repeat(print_hi, num_times=4)
回答1:
For the case of the repeat
decorator, the equivalent is:
print_hi = repeat(num_times=4)(print_hi)
Here, repeat
takes a num_times
argument and returns the decorator_repeat
closure, which itself takes a func
arguments and returns the wrapper_repeat
closure.
回答2:
repeat(num_times)
returns a function and that function is used to decorate print_hi
.
@repeat(num_times=4)
def print_hi(num_times):
...
amounts to
f = repeat(num_times)
print_hi = f(print_hi)
The function that repeat
returns is decorator_repeat
, which decorates print_hi
.
来源:https://stackoverflow.com/questions/52606101/decorator-function-syntax-python