Python 理解闭包在装饰器和函数包装器参数中的作用

Python 理解闭包在装饰器和函数包装器参数中的作用,python,function,closures,decorator,python-decorators,Python,Function,Closures,Decorator,Python Decorators,在下面的代码中,我试图理解传递给修饰函数的参数是如何传递给包装函数中的参数的: 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))

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

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>
my_get_text("John")
def get_文本(名称):
返回“lorem ipsum,{0}dolor sit amet”。格式(名称)
def p_装饰(功能):
def func_包装(*参数,**kwargs):
返回“{0}

”。格式(func(*args,**kwargs)) 返回函数包装器 my_get_text=p_装饰(get_text) 打印我的“获取”文本(“John”) #输出lorem ipsum,John dolor sit amet

通过谷歌搜索,我发现内部函数
func\u wrapper()
可以通过闭包访问封闭范围内的变量或对象(我想我已经正确理解了这一点)

我不理解的是,传递给
get_text(name)
的参数
name
的值是如何被内部函数
func\u wrapper()
中的
*args
**kwargs
访问的(或赋予或分配给
*


我认为我的理解是正确的,整个
get_text(name)
函数及其参数
name
被传递给
p_detain()
,因此在
p_detain()
的范围内可用,但是参数是如何传递给
func\u包装器()的呢
允许访问传递给
获取文本(名称)
的参数?允许这种情况发生的过程或方法是什么

当您执行
my\u get\u text=p\u装饰(get\u text)
时,您将
my\u get\u text
设置为调用
p\u装饰(get\u text)
的结果。调用
p\u decoration
的结果是您的
func\u包装器
。因此,当您调用
my\u get\u text
时,实际上是在调用
func\u wrapper

然后看看
func\u包装器的功能。它接受任何参数(
*args
*kwargs
)并将它们传递给
func
。由于在调用
p\u
func
被设置为
get\u text
,因此此调用
get\u text
的参数与调用
my\u get\u text
的参数相同

有一个闭包是对的,但是闭包实际上与调用
my\u get\u text(“John”)
中的参数的传递方式没有任何关系。闭包的作用是确保
func
(即
get\u text
)的值“保存”在
func\u包装中,以便返回的包装“知道”它包装的是哪个函数。但是一旦创建了包装函数,调用它时发生的实际参数传递就是正常的参数传递。您使用参数调用一个函数,该函数使用相同的参数调用另一个函数。与此无异:

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

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

如果现在调用
bar
,它将调用
foo
foo
使用相同的参数调用,因为
bar
使用相同的参数调用它
bar
。类似地,在您的示例中,
get\u text
获取参数,因为
func\u wrapper
调用
get\u text
的参数与调用
func\u wrapper
的参数相同。

当您执行
my\u get\u text=p\u decoration(get\u text)
时,您将
my\u get\u text
设置为调用
p\u decort(get\text)的结果
。调用
p\u decoration
的结果是您的
func\u包装器
。因此,当您调用
my\u get\u text
时,实际上是在调用
func\u wrapper

然后看看
func\u包装器的功能。它接受任何参数(
*args
*kwargs
)并将它们传递给
func
。由于在调用
p\u
func
被设置为
get\u text
,因此此调用
get\u text
的参数与调用
my\u get\u text
的参数相同

有一个闭包是对的,但是闭包实际上与调用
my\u get\u text(“John”)
中的参数的传递方式没有任何关系。闭包的作用是确保
func
(即
get\u text
)的值“保存”在
func\u包装中,以便返回的包装“知道”它包装的是哪个函数。但是一旦创建了包装函数,调用它时发生的实际参数传递就是正常的参数传递。您使用参数调用一个函数,该函数使用相同的参数调用另一个函数。与此无异:

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

def bar(x, y):
    return foo(x, y)
如果现在调用
bar
,它将调用
foo
foo
使用相同的参数调用,因为
bar
使用相同的参数调用它
bar
。同样,在您的示例中,
get\u text
获取参数,因为
func\u wrapper
调用
get\u text
时使用相同的参数调用
func\u wrapper

my_get_text = p_decorate(get_text)
…函数
p_decoration()
通过
func=get_text
执行。它定义了一个新函数
func\u wrapper()
,从而可以访问函数定义时设置的
func

因此,
p_decoration()
的返回值是一个新创建的函数,其签名为
func_wrapper(*args,**kwargs)
,它还可以方便地访问
func
变量。请注意,再次调用
p\u decoration()
将创建一个不同的
func\u包装器()
函数,其中包含一个不同的
func
变量

现在,当您调用这个新创建的函数时:

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>
my_get_text("John")
你实际上是在说:

def func_wrapper(*args, **kwargs):
    func = get_text
    # ...
如果您使用一个位置参数调用它,那么当您调用时,它相当于
args=(“John”),kwargs={}

my_get_text = p_decorate(get_text)