This article,从各种stackoverflow问题中多次链接,描述了带参数的装饰器在语法上与没有参数的装饰器的区别。
__init__()
是执行装饰的唯一方法,每次调用装饰__call__()
时都会调用sayHello()
。”__call__()
,它只能接受一个参数(函数对象),并且必须返回替换原始的装饰函数对象。请注意,__call__()
现在仅在装饰期间调用一次,之后,您从__call__()
返回的修饰函数将用于实际调用。“文章中给出的解释并没有告诉我为什么语言是这样建立的:
虽然这种行为有意义 - 构造函数现在用于捕获装饰器参数,但对象
__call__()
不能再用作装饰函数调用,因此您必须使用__call__()
进行装饰 - 第一次看到它时仍然令人惊讶
此设置有两个相关功能让我感到不舒服:
__init__
和__call__
,但是它们意味着不同的东西?__call__
用于调用装饰函数以外的目的(顾名思义,至少来自无参数情况)?鉴于__call__
仅在__init__
之后立即调用,为什么不直接将要装饰的函数作为参数传递给__init__
并处理__call__
中__init__
所发生的一切。 {1}}而不是?答案 0 :(得分:9)
这是因为它是在两种情况下都被调用的装饰器对象。为了更清楚,鉴于此:
def my_decorator(a):
def wrapper(f):
def wrapped_function():
return f() + a
return wrapped_function
return wrapper
这样:
@my_decorator(5)
def function():
return 5
相当于:
decorator = my_decorator(5)
@decorator
def function():
return 5
在无参数情况下发生的事情是装饰器被直接调用,而不必返回一个将对象作为参数进行装饰的函数。