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)