该函数如何找到另一个变量的值?

时间:2016-02-26 02:46:15

标签: python scope

以下是代码:

以上代码输出:

def caller(callee):
    callee()

def wrapper():

    def a():
        print v0

    for i in range(5):
        v0 = i*i
        caller(a)

wrapper()

但我不明白0 1 4 9 16 如何解析变量a。我找不到有关此语言功能的相关python文档。

3 个答案:

答案 0 :(得分:2)

函数中定义的变量范围包括其中的所有嵌套函数。因此wrapper()中定义的变量可以在a()中访问,因为此函数嵌套在其中。这被称为词法范围,它通常用于创建闭包。

Python Resolution of Names文档中对此进行了解释:

  

范围定义块中名称的可见性。如果在块中定义了局部变量,则其范围包括该块。如果定义发生在功能块中,则范围将扩展到定义块中包含的任何块,除非包含的块为名称引入了不同的绑定。

答案 1 :(得分:1)

每次调用a时都会定义函数wrapper。当调用a的给定实例时,它会在其定义的上下文中查找v0,这是对定义它的wrapper的特定调用。在调用a时,v0已在wrapper内定义,a使用v0的定义。

在此示例中,调用wrapper时,定义a的{​​{1}}的调用仍处于活动状态,但不一定如此。换句话说,a可以返回,并且仍然可以调用对该上下文的wrapper的引用。在这种情况下,它将是一个闭包。但是在这个例子中不会发生这种情况。

这是一个使用闭包的示例:

a

输出结果为:

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

f1 = foo(123)
f2 = foo(456)

print(f1())
print(f2())

调用123 456 时,它会返回foo的实例,该实例在调用bar的上下文中评估x。在第一次调用中,foo为123,在第二次调用中为x。即使在调用456之后,这些绑定仍然存在。

答案 2 :(得分:0)

请记住,在调用函数之前,函数中的所有代码都不会运行。在调用a()时,v0已在外部范围中定义,因此它可以识别变量并对其进行评估。