nonlocal
nonlocal 语句会使得所列出的名称指向在它之前已经存在的,和它最近并且在包含它的作用域中绑定,除全局变量以外的变量。
这种功能很重要,因为绑定的默认行为是先搜索局部命名空间。这个语句允许被封装的代码重新绑定局部作用域以外且非全局(模块)作用域当中的变量。
举例如下:
a = '全局'
def f():
a = 'f' # f 中已经存在的 a, 包含 f2
def f1():
a = 'f1' # f1 中的局部变量
def f2():
nonlocal a # 和他最近且包含的是 'f'
a = 'f2'
def f3():
global a
a = 'f3'
# 调用 f1 不改变 a = 'f'
f1()
print(a)
# 调用 f2, nonlocal 将 a = 'f' 重新绑定为 a = 'f2'
f2()
print(a)
# 调用 f3, global 将 a 声明为全局变量,
# 并将 a = '全局' 重新绑定为 a = 'f3'
# 但在 f 这个局部中,a 仍然是 'f2'
f3()
print(a)
f() # 调用 f 使绑定都生效
print(a)
f
f2
f2
f3
# 不存在不可以绑定
def f():
nonlocal a
a = 1
f()
File "<ipython-input-3-3706e217f701>", line 2
nonlocal a
^
SyntaxError: no binding for nonlocal 'a' found
# 不是包含它的作用域,不可以绑定
def f():
def f1():
a = 0
f1()
nonlocal a
a = 1
f()
File "<ipython-input-4-a036260d029b>", line 5
nonlocal a
^
SyntaxError: no binding for nonlocal 'a' found
# 全局变量,不可以绑定
a = 0
def f():
nonlocal a
a = 1
f()
File "<ipython-input-5-87297c0b0eeb>", line 4
nonlocal a
^
SyntaxError: no binding for nonlocal 'a' found