定义在当前作用域之外实现的Python函数的变量

时间:2018-01-12 00:46:25

标签: python

我想知道为什么以下有效:

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?我正在玩函数装饰器,但无法弄清楚如何将变量暴露给我传递给装饰器的函数。

2 个答案:

答案 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中,在另一个范围内定义的函数(即嵌套函数)可以访问外部函数作用域(因此也可以访问其变量)