This article ,多次链接到各种 stackoverflow 问题,描述了带参数的装饰器与不带参数的装饰器在语法上有何不同。
- 不带参数的装饰器:“请注意,
__init__()
是执行装饰的唯一调用方法,每次调用装饰后的时都会调用
。”__call__()
>sayHello() - 带参数的装饰器:“现在装饰过程调用构造函数,然后立即调用
__call__()
,它只能接受一个参数(函数对象)并且必须返回装饰后的函数对象替换原来的。注意__call__()
现在只调用一次,在装饰期间,然后你从__call__()
返回的装饰函数用于实际通话。”
文中给出的解释并没有告诉我为什么要这样设置语言:
Although this behavior makes sense -- the constructor is now used to capture the decorator arguments, but the object
__call__()
can no longer be used as the decorated function call, so you must instead use__call__()
to perform the decoration -- it is nonetheless surprising the first time you see it
此设置有两个相关功能让我感到不舒服:
- 为什么要提供一种方法来制作无参数装饰器,而不仅仅是更通用的指定装饰器方法的特例?为什么在两者中都使用
__init__
和__call__
,但它们的含义不同? - 为什么在带有参数的装饰器中使用
__call__
的目的不是为了调用被装饰的函数(顾名思义,至少来自无参数的情况)?鉴于__call__
仅在__init__
之后立即调用,为什么不将要装饰的函数作为参数传递给__init__
并处理所有可能会发生的事情在__init__
中的__call__
中发生?
最佳答案
这是因为在这两种情况下都调用了装饰器对象。为了更清楚,鉴于此:
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
在无参数的情况下,装饰器会被直接调用,而不必返回一个将要装饰的对象作为参数的函数。
关于python - 为什么带参数的 Python 装饰器与不带参数的装饰器在句法上不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20234533/