我正在学习装饰器,并遇到了一个装饰器争论的例子。但是,这对我来说有点令人困惑,因为我了解到(注:此问题的示例是 [[大部分 this article):
def my_decorator(func):
def inner(*args, **kwargs):
print('Before function runs')
func(*args, **kwargs)
print('After function ran')
@my_decorator
def foo(thing_to_print):
print(thing_to_print)
foo('Hello')
# Returns:
# Before function runs
# Hello
# After function ran
等于
foo = my_wrapper(foo)
所以,对于我来说,某些东西如何接受参数是没有意义的,为了更好地解释,这是一个接受参数的装饰器示例:
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
@repeat(num_times=4)
def greet(name):
print(f"Hello {name}")
greet('Bob')
# Returns:
# Hello Bob
# Hello Bob
# Hello Bob
# Hello Bob
所以当我看到这个时,我在想:
greet = repeat(greet, num_times=4)
我知道那是不对的,因为num_times
是应该传递的唯一参数。那么,没有[@repeat(num_times=4)
-symbol-syntax]的@
的正确等效项是什么?谢谢!
从您的示例代码中,repeat
返回decorator_repeat
定义。因此,您可以调用decorator_repeat
函数并按以下方式传递greet
函数:
def greet(name):
print(f"Hello {name}")
greet = repeat(num_times=4)(greet)
greet('Bob')
# Hello Bob
# Hello Bob
# Hello Bob
# Hello Bob
在这种情况下将是:
greet = repeat(num_times=4)(greet)
这将解释repeat
中的两个嵌套级别(您可能需要说函数“两次”)。