Python 3中的"nonlocal"怎么用?
nonlocal
在 Python 3.x 中有什么用?
为了避免调试问题,特别是当提问者需要使用 nonlocal
但自己没有意识到时,请参考 是否可以修改在外部作用域但不是全局作用域中的变量?。
虽然 Python 2 从 2020 年 1 月 1 日起 官方不再支持,但如果你因为某种原因需要维护 Python 2.x 的代码,并且需要一个类似于 nonlocal
的功能,可以查看 Python 2.x 中的 nonlocal 关键字。
10 个回答
56
在谷歌搜索“python nonlocal”时,找到了一个提案,叫做 PEP 3104,里面详细描述了这个语法和它的原理。简单来说,它的工作方式和 global
语句完全一样,只不过它是用来指代那些既不是全局变量也不是局部变量的变量。
下面是一个简单的例子,展示你可以用这个做什么。我们可以把计数器生成器改写成使用这个语法,这样看起来更像一些支持闭包的编程语言的写法。
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
显然,你也可以把它写成一个生成器,比如:
def counter_generator():
count = 0
while True:
count += 1
yield count
但是虽然这个写法在 Python 中是非常标准的,但对于初学者来说,第一种写法可能会更容易理解。正确使用生成器,尤其是调用返回的函数,常常让人感到困惑。第一种写法明确地返回了一个函数。
129
简单来说,它让你可以在一个外部的(但不是全局的)范围内给变量赋值。想了解更多细节,可以查看 PEP 3104。
657
对比一下,不使用 nonlocal
的情况:
x = 0
def outer():
x = 1
def inner():
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# inner: 2
# outer: 1
# global: 0
再看看这个,使用了nonlocal
,这样 inner()
里的 x
现在也变成了 outer()
里的 x
:
x = 0
def outer():
x = 1
def inner():
nonlocal x
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# inner: 2
# outer: 2
# global: 0
如果我们使用global
,那么 x
就会绑定到真正的“全局”值:
x = 0
def outer():
x = 1
def inner():
global x
x = 2
print("inner:", x)
inner()
print("outer:", x)
outer()
print("global:", x)
# inner: 2
# outer: 1
# global: 2