12

我正在尝试对 Python 3 源代码中的范围进行一些分析,但我对非本地语句语句在类定义中的工作方式感到困惑。

据我了解,类定义在一个新的命名空间内执行它的主体(称为dict)并将类名绑定到类型(name,bases,dict)的结果。只要非本地 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

谁能在这里解释函数定义的闭包和类定义之间的区别?

4

2 回答 2

13

词法范围仅适用于函数命名空间,否则在类中定义的方法将能够“看到”类级别的属性(这是设计使然——这些属性必须作为self方法内部的属性来访问)。

导致方法引用跳过类级别变量的相同限制也使nonlocal关键字无法发挥其魔力。(global但确实有效,因为这不依赖于词法作用域机制)

于 2011-03-29T01:41:58.337 回答
4

Python 处理类和函数定义的方式截然不同。例如,您A.v不是 A 的变量,而是它的一个属性。因此,由类创建的命名空间不是作用域。nonlocal当您尝试使用它时,它不起作用,我并不感到惊讶。

于 2011-03-28T23:41:00.787 回答