python - 为什么带参数的 Python 装饰器与不带参数的装饰器在句法上不同?

标签 python arguments decorator callable

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

此设置有两个相关功能让我感到不舒服:

  1. 为什么要提供一种方法来制作无参数装饰器,而不仅仅是更通用的指定装饰器方法的特例?为什么在两者中都使用 __init____call__,但它们的含义不同?
  2. 为什么在带有参数的装饰器中使用 __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/

相关文章:

python - Tensorflow 对象检测中的输入张量与 Python 签名不兼容

swift - 没有参数的方法正在调用参数

java - 如果语句依赖于传递什么命令行参数?

python :TypeError: this constructor takes no arguments

python - 如何通过 flask.Blueprint.route 装饰器传递类的 self ?

python - Pandas 分组并分配一个组ID然后取消分组

python - 删除\u2018 和\u2019 字符

python - 无法安装win32gui

angular - 使用 createReducer 函数时为生产构建 angular+ngrx 8 时出错

python - 在将函数附加为对象属性的装饰器中使用 functools.partial