在不同情况下将带参数的函数传递给装饰器的区别

Difference between passing functions with arguments to a decorator in different scenario

我从 Corey Schafer 的 Python 装饰器教程中获得了这段代码。我给出以下两个代码。

def decorator_function(original_function):
    def wrapper_function():
        print("Wrapper executed before {}".format(original_function.__name__))
        return original_function()
    return wrapper_function

@decorator_function
def display():
    print("display func ran")

def function_info(name,age):
    print("Function info has {} and {} as arguments.".format(name, age))

display()
function_info('John',23) 

这会正确执行代码。但是如果我们采用 function_info(name,age) 方法,它传递的是参数,而不是给出任何错误。

同时,下面所述的代码将 args 和 kwargs 作为参数。

def decorator_function(original_function):
    def wrapper_function(*args,**kwargs):
        print("Wrapper executed before {}".format(original_function.__name__))
        return original_function(*args,**kwargs)
    return wrapper_function

@decorator_function
def display():
    print("display func ran")

def function_info(name,age):
    print("Function info has {} and {} as arguments.".format(name, age))

display() 
function_info('Jim',23)

谁能给我解释一下区别?

为什么在 CODE - 1 中,当两种方法都在同一个装饰器中时,function_info(name,age) 不会给出任何错误,但是在 CODE - 2 中,当两种方法分别装饰时, function_info(name, age) 需要 args 和 kwargs?

两个函数的输出基本相同 - 无论您是否使用参数 *args,**kwargs(使用 https://www.onlinegdb.com/online_python_interpreter 测试)。

代码-1:

Wrapper executed before display
display func ran
Function info has John and 23 as arguments.

代码 - 2:

Wrapper executed before display
display func ran
Function info has Jim and 23 as arguments.

问题是装饰器只用在没有参数的函数显示上。

如果你把

@decorator_function
def function_info(name,age):
    print("Function info has {} and {} as arguments.".format(name, age))

然后 - 对于这两个代码 - 你需要 *args,**kwargs 因为 wrapper_function() 在 function_info() 执行之前执行。由于 function_info() 接受参数,因此装饰器中的 wrapper_function() 也需要参数,否则解释器会抱怨一个函数有两个参数需要 none.

输出:

Wrapper executed before display
display func ran
Wrapper executed before function_info
Function info has Jim and 23 as arguments.