我想知道为什么以下有效:
def wrapper():
def wrap(p=10):
def f():
print(p)
f()
return wrap
f2 = wrapper()
f2()
但这不是:
def f():
print(p)
def enhance(f):
def wrap(p=10):
f()
return wrap
f2 = enhance(f)
f2() # NameError: name 'p' is not defined
有没有办法可以修改第二个场景,以便定义变量p
?我正在玩函数装饰器,但无法弄清楚如何将变量暴露给我传递给装饰器的函数。
答案 0 :(得分:5)
我想我明白你的真实要求。你正在考虑装饰器,而不是变量范围。你说你无法弄清楚如何“将变量暴露给我传递给装饰器的函数。”在您的情况2中,您传递给enhance
的函数不会拥有任何变量(参数)。假设我们给它一个参数,如下:
def f(p):
print(p)
def enhance(f):
def wrap(p=10):
f(p) # pass the argument to f
return wrap
f2 = enhance(f)
f2()
现在你有一个名为enhance
的函数,它可以用作装饰器。要装饰的函数需要一个参数。装饰器将使用一个新函数替换此函数,该函数可以使用一个或零参数调用。如果在没有参数的情况下调用,它将获得值“10”作为默认值。
装饰器用另一个函数替换一个函数。一般来说,提供参数不是装饰者的工作,除非您正在尝试执行默认参数。参数来自调用函数的代码。
答案 1 :(得分:0)
因为在示例2中,您引用的p
未在一个函数中定义,并在另一个函数中用作参数,每个函数都在自己的范围内定义。
在示例1中,在另一个范围内定义的函数(即嵌套函数)可以访问外部函数作用域(因此也可以访问其变量)