给出下面的例子,受另一个SO问题的启发:
x = 0
def func1():
x = 1
def func2():
x = 2
def func3():
KEYWORD x # scope declaration
x = 3
func3()
func2()
func1()
以global
和nonlocal
为关键字,x
的值分别为0
和2
,而不是3
。
Python是否提供了在func3()
中使用func1()
的x
的作用域的机制?或者这里只能访问global
,func2
和func3
作用域?
不能使用nonlocal
指定特定的作用域。它将始终选择包含指定变量的最近的封闭作用域。
由于Python使用词法作用域,因此陷入这种情况的唯一方法是自己为所有作用域编写代码。(例如,当你写func3
时,你知道它嵌套在func2
中,所以你知道func2
范围内的所有变量。)只要在编写代码时不要在每个作用域中重用相同的名称,nonlocal
就会做正确的事情。(我们将首先忽略编写这种深度嵌套代码的问题。)
x_global = 0
def func1():
x_first = 1
def func2():
x_second = 2
def func3():
nonlocal x_first # scope declaration
x_first = 3
func3()
func2()
func1()
相反,让我们假设Python使用了动态作用域。
x = 9
def func1():
nonlocal x
x = 3
def func2():
x = 1
func1()
print(x)
def func3():
print(x)
func2() # Prints 3
print(x) # Prints 9; the global variable hasn't been changed
func1()
print(x) # Prints 3; the global variable *has* changed.
被func1
修改的变量现在取决于func1
被调用的作用域。
在实际的Python中,上面的序列将输出
1
3
3
作为func1
将总是修改全局变量,无论是从全局作用域还是从func2
的局部作用域调用。