NameError 与全局 NameError

NameError vs global NameError

我正在尝试重现我遇到的一个错误:

NameError: global name 'sdrent' is not defined

但是,如果我打开解释器并输入 sdrent,我会收到以下错误:

>>> sdrent
NameError: name 'sdrent' is not defined

NameError: global name...NameError: name... 有什么区别,我该如何重现前者?

这似乎发生在函数或方法的上下文中,其中 LEGB 在 G(lobal) 处停止,已经知道内置函数并且 exits/complains 在该范围内。

例如,要重现:

>>> def hi():
...     sdrent
...
>>> hi()
NameError: global name 'sdrent' is not defined

或者更简单:

>>> (lambda: sdrent)()
NameError: global name 'sdrent' is not defined

并且在 class 方法中:

>>> class X:
        def __call__(_): sdrent
>>> X()()
NameError: global name 'sdrent' is not defined

CPython 有两个用于全局变量查找的操作码,LOAD_GLOBAL and LOAD_NAMELOAD_NAME 在全局变量之前查找局部变量,而 LOAD_GLOBAL 直接查找全局变量。 LOAD_NAME 主要用于 class 语句,但在没有 global 声明的情况下,编译器也恰好发出 LOAD_NAME 用于模块级别的全局变量查找。

回到 Python 3.4 之前,LOAD_GLOBAL 曾经在查找失败时说 global name 'whatever' is not defined,而 LOAD_NAME 曾经说 name 'whatever' is not definedchanged 当有人争辩说“全局”对于有人错误输入局部变量名称的情况时会造成混淆。

您使用的是 Python 2.7。当您 运行 在顶层查找一个不存在的名称的变量时,您会收到 LOAD_NAME 错误消息,但在函数内部,您会收到 LOAD_GLOBAL 错误消息,它仍然显示“全局" 在 Python 2.