Python类定义中的nonlocal语句
我正在尝试分析Python 3源代码中的作用域,但在理解类定义中的nonlocal语句时遇到了困难。
根据我的理解,类定义的内容会在一个新的命名空间中执行(可以把它想象成一个字典),并将类名绑定到type(name, bases, dict)的结果上。只要nonlocal x指向的是在外部非本地作用域中绑定的变量,它应该可以正常工作。
基于这个理解,我期待以下代码可以编译并运行:
class A:
v = 1
class B:
nonlocal v
v = 2
但这段代码却失败了,错误信息是:
SyntaxError: no binding for nonlocal 'v' found
而下面这段代码则可以完美运行:
def A():
v = 1
class B:
nonlocal v
v = 2
有没有人能解释一下函数定义的闭包和类定义之间的区别?
2 个回答
5
Python 对类和函数的定义处理得有点不同。比如,你的 A.v
不是 A 的一个变量,而是 A 的一个属性。类创建的命名空间并不是一个作用域。所以,我并不奇怪你用的 nonlocal
没有起作用。
13
词法作用域只适用于函数的命名空间,否则在类里面定义的方法就能“看到”类级别的属性(这是设计使然——这些属性必须通过方法中的self
来访问)。
导致类级别变量在方法中无法直接访问的限制,也让nonlocal
关键字无法发挥作用。(不过global
是可以用的,因为它不依赖于词法作用域的机制)