Python类定义中的nonlocal语句

15 投票
2 回答
5954 浏览
提问于 2025-04-16 14:36

我正在尝试分析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是可以用的,因为它不依赖于词法作用域的机制)

撰写回答