Skip to main content
 首页 » 编程设计

python之了解闭包在装饰器和函数包装器参数中的作用

2025年05月04日31zlslch

我试图在下面的代码中理解传递给装饰函数的参数似乎是如何传递给包装函数中的参数的:

def get_text(name): 
   return "lorem ipsum, {0} dolor sit amet".format(name) 
 
def p_decorate(func): 
   def func_wrapper(*args, **kwargs): 
       return "<p>{0}</p>".format(func(*args, **kwargs)) 
   return func_wrapper 
 
my_get_text = p_decorate(get_text) 
 
print my_get_text("John") 
 
# <p>Outputs lorem ipsum, John dolor sit amet</p> 

通过尝试使用 Google,我收集到内部函数 func_wrapper() 可以通过闭包访问封闭范围内的变量或对象(我认为我对这一点的理解是正确的)。

我不明白的是,传递给 get_text(name) 的参数 name 的值究竟是如何被访问(或赋予或分配给) *args 或 **kwargs 在内部函数 func_wrapper() 中。

我认为我对整个 get_text(name) 函数及其参数 name 传递给 p_decorate() 的理解是正确的因此在 p_decorate() 范围内可用 — 但是传递给 func_wrapper() 的参数如何允许访问传递给 get_text(name) 的参数?允许这种情况发生的过程或方法是什么?

请您参考如下方法:

当您执行 my_get_text = p_decorate(get_text) 时,您将 my_get_text 设置为调用 p_decorate(get_text) 的结果。调用 p_decorate 的结果是您的 func_wrapper。因此,当您调用 my_get_text 时,实际上是在调用 func_wrapper。

然后看看func_wrapper做了什么。它接受任何参数(*args 和 *kwargs)并将它们传递给 func。由于 func 在调用 p_decorate 时设置为 get_text,因此调用 get_text 时使用与 相同的参数my_get_text 被调用。

闭包是对的,但闭包实际上与调用 my_get_text("John") 中的参数如何传递没有任何关系。闭包的作用是确保func(即get_text)的值被“保存”在func_wrapper中,从而使返回的包装器“知道”它正在包装哪个功能。但是一旦创建了包装函数,调用它时发生的实际参数传递只是正常的参数传递。您使用参数调用一个函数,该函数使用相同的参数调用另一个函数。它与此没有什么不同:

def foo(x, y): 
    return x+y 
 
def bar(x, y): 
    return foo(x, y) 

如果您现在调用 bar,它会调用 foo。 foo 使用相同的参数调用,因为 bar 使用相同的参数调用它 bar 被调用。同样,在您的示例中 get_text 获取参数,因为 func_wrapper 调用 get_text 使用相同的参数 func_wrapper 被调用。