这个问题是 a question about Python variable scope 的后续问题。 .其他问题 q1 , q2和 answers可以在 SO 上找到,甚至更多。
官方Python documentation , 和 PEP 3104应该解释细节,但对我来说,它们似乎并不完全不言自明。
我要解决的主题是重构包含 nonlocal
的代码/global
通过将该代码向上/向下移动一级层次结构。
我不明白的是 Python 引用中这句话的含义:
Names listed in a nonlocal statement, unlike to those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).
给定以下关于全局范围的代码:
var = 0
def outer():
global var # line A
var = 1
def inner():
nonlocal var # line B
var = 2
print('inner:', var)
inner()
print('outer:', var)
outer()
print('main:', var)
执行引发错误:
SyntaxError: no binding for nonlocal 'var' found
该代码有效(当然,如果注释掉了 A 行,则具有不同的语义:
inner: 2
outer: 2
main: 0
或 B 行被注释掉:
inner: 2
outer: 1
main: 1
然而,在上面的例子中,由于
nonlocal
应该将 var 绑定(bind)到“封闭范围”,我原以为 A 行将外部/var 绑定(bind)到全局范围,B 行然后查找外部/var 并将内部/var 重新绑定(bind)到 global/var。相反,它似乎根本找不到它(我想是由于 A 行中的重新绑定(bind))并引发了错误。我期望的结果是:
inner: 2
outer: 2
main: 2
这只是 Python 中范围界定的困惑心态的又一个例子吗?
或者,为了使这是一个 build 性的问题:
global
和 nonlocal
,反之亦然)? outer()
的作者怎么能做到?更改最外层(在本例中为全局)级别和 inner()
的代码水平必须被触及? - 在我对这门语言的谦虚理解中,应该避免像这样的结构(依赖于闭包)。其他人已经建议使用其他语言功能(classes、func attrs)来实现这种上下文敏感性。
最佳答案
global
和 nonlocal
不打算合并。它们的含义不同:
global
表示名称存在于模块级别nonlocal
表示名称存在于外部词法函数范围内 您得到原始异常的原因是您告诉 Python
var
是非本地的(意味着它在外部函数定义中),但有 没有功能级绑定(bind)对于 var
在任何外部函数定义中,因为您在外部函数中告诉 Python var
是全局性的。
关于scope - Python的非本地取决于层次结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8050502/