python - 在全局命名空间中查找类定义中未绑定(bind)的局部变量——这是什么意思?

标签 python scoping

最后一段https://docs.python.org/3/reference/executionmodel.html#resolution-of-names

Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace.

引用文本的最后一句话是什么意思?一开始我从中推断,下面的代码会打印1

a = 1

def foo():
    a = 2
    def bar():
        class Bar:
            b = a
        print(Bar.b)
    bar()

foo()

但我错了 - 由上面的代码组成的模块在运行时打印 2,即类定义中的名称 a,即使它没有绑定(bind)在类定义 block 中而不是绑定(bind)在它外面的本地 block 中,不会在全局命名空间中查找,这与文档所说的相反。

我尝试了下面描述的另一个代码片段(使用 del 语句,这是一个绑定(bind)变量的结构)

a = 1

def foo():
    a = 2
    def bar():
        class Bar:
            del a
        print(Bar.b)
    bar()

foo()

但是 del 语句引发了 NameError: name 'a' is not defined

所以,我不明白,那句话是什么意思?

最佳答案

According to the docs ,

if a name is bound in a block, it is a local variable of that block, unless declared as nonlocal or global.

在您的第一个代码块中,a 未绑定(bind)到您的 class Bar 定义中的任何内容,因此它不是该 block 的局部变量。

绑定(bind)名称的一种方法是在赋值语句的左侧使用它。这是一个例子。

a = 1
def foo():
    a = 2
    class Bar:
        b = a
        a = 3
    print(Bar.b)
foo()

结果:

1

这演示了“未绑定(bind)的局部变量在全局命名空间中查找”的原则——b = a 使用全局a 的值而不是值a 局部于 foo


在您的第二个示例中,a 被认为是 class Bar block 的本地部分,因为“目标出现在 del 语句中也被认为是绑定(bind)的”以确定名称的范围。但是“在全局命名空间中查找未绑定(bind)的局部变量”是不相关的,因为 del 不需要查找名称的值来解除绑定(bind)。

为了更好地衡量,我们可以通过实验确认 del 语句向解释器发出信号,表明名称应被视为本地名称。

a = 1
def foo():
    a = 2
    class Bar:
        print(a)
        del a
foo()

结果:

1
Traceback (most recent call last):
  File "C:\Users\Kevin\Desktop\test.py", line 7, in <module>
    foo()
  File "C:\Users\Kevin\Desktop\test.py", line 4, in foo
    class Bar:
  File "C:\Users\Kevin\Desktop\test.py", line 6, in Bar
    del a
NameError: name 'a' is not defined

这里我们看到 print(a) 成功地查找了局部变量 a 的值,然后在下一行它崩溃了,因为 del 无法删除未绑定(bind)的局部变量。

关于python - 在全局命名空间中查找类定义中未绑定(bind)的局部变量——这是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56580323/

相关文章:

python - 如何分隔逗号分隔的列表

python - 在Python中运行一个线程一段时间

r - 使用dplyr将变量作为函数的默认参数

kotlin - kotlin…ArrayOf范围界定问题

python - 如何组合两列的浮点值并将其放入数据帧的另一列中?

Android JetCreator 深度复制错误

python - 如何在 Python 中读取类型为 complex64 值的二进制文件

Javascript: z = z || [] 在不使用 VAR 时抛出错误 - 为什么?

R将线性模型传递给函数内的另一个函数

javascript - 对象字面量方法的范围