为什么Python装饰器的参数在语法上与没有参数的参数不同?

kuz*_*roo 8 python arguments callable decorator

本文从各种stackoverflow问题中多次链接,描述了带参数的装饰器在语法上与不带参数的装饰器的区别.

  • 没有参数的装饰器:"请注意,这__init__()是执行装饰的唯一方法,__call__()每次调用装饰时都会调用它sayHello()."
  • 带参数的装饰器:"现在装饰过程调用构造函数,然后立即调用__call__(),只能接受一个参数(函数对象),并且必须返回替换原始的装饰函数对象.请注意,__call__()现在只调用一次,在装修期间,之后您返回的装饰功能将__call__()用于实际通话."

文章中给出的解释并没有告诉我为什么语言是这样建立的:

虽然这种行为是有道理的 - 构造函数现在用于捕获装饰器参数,但该对象__call__()不能再用作装饰函数调用,因此您必须使用它__call__()来执行装饰 - 它仍然是令人惊讶的第一次你看到了

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

  1. 为什么提供一种方法来制作无参数装饰器,这不仅仅是指定装饰器的更通用方法的特例?为什么使用__init____call__在这两个,但他们意味着不同的事情?
  2. 为什么__call__在具有参数的装饰器的情况下使用除了调用装饰函数之外的其他目的(顾名思义,至少来自无参数情况)?由于__call__只有后立即调用__init__,为什么不直接传递给装饰作为参数传递给函数__init__和处理,将在发生一切__call____init__呢?

Ben*_*nno 9

这是因为它是在两种情况下被调用的装饰器对象.为了使它更清楚,鉴于此:

def my_decorator(a):
    def wrapper(f):
        def wrapped_function():
            return f() + a
        return wrapped_function
    return wrapper
Run Code Online (Sandbox Code Playgroud)

这个:

@my_decorator(5)
def function():
    return 5
Run Code Online (Sandbox Code Playgroud)

相当于:

decorator = my_decorator(5)

@decorator
def function():
    return 5
Run Code Online (Sandbox Code Playgroud)

无争论情况下发生的是装饰器被直接调用,而不必返回一个将对象作为参数进行装饰的函数.

  • 换句话说,`wrapper`是装饰器,`my_decorator`不是装饰器,它是_returns_装饰器(在这种情况下为`wrapper`)的函数.然而,将`my_decorator`视为"带参数的装饰器"感觉很自然 (4认同)