首页 > 解决方案 > NameError 在理解中引用类变量

问题描述

当我NameError: name 'ID' is not defined试图在字典理解中访问类变量时,例如在class A. 在没有理解的情况下引用它可以正常工作(请参阅 参考资料class B)。所以我的问题是,为什么它会在 A 类中抛出 NameError 而在 B 类中却没有?

class A:
    ID = "This is class A."

    test = {str(i): ID for i in range(5)}

class B:
    ID = "This is class B."

    test = f"{ID}"

标签: pythonclassvariablesreferencenameerror

解决方案


Python中名称解析的注意事项:

类定义块和参数在名称解析的上下文中是特殊的exec()eval()类定义是可以使用和定义名称的可执行语句。这些引用遵循名称解析的正常规则,但在全局命名空间中查找未绑定的局部变量除外。类定义的命名空间成为类的属性字典。 类块中定义的名称范围仅限于类块;它没有扩展到方法的代码块——这包括理解和生成器表达式,因为它们是使用函数范围实现的。这意味着以下将失败。

ID在类定义中声明了一个变量,使其成为classstatic变量。所以它的范围仅限于类块,因此你不能在comprehensions.

你可以在python 文档中阅读更多关于它的信息

考虑这些例子,

示例 #1:

class A:
    ID = "This is class A."
    print(ID)

现在,当您执行时>>>A(),输出将This is class A是完全正常的,因为变量的范围ID仅限于类A


示例 #2:

class B:
    L = [ 1, 2, 3, 4, 5, 6, 7]
    print([i * 2 for i in L])

现在,当您执行>>>B()输出时[2, 4, 6, 8, 10, 12, 14],这完全没问题,因为列表的范围L仅限于 B 类


示例#3:

class C:
   L = [ 1, 2, 3, 4, 5, 6, 7]
   print([L[i] * 2 for i in range(7)])

现在执行>>>C()将引发一个NameError说明L未定义名称。


推荐阅读