当前位置: 首页 > news >正文

【Python】类定义过程中 列表推导式获取类变量的问题

文章目录

    • 提出问题
    • 问题分析
    • 验证
      • 打印推导式作用域中的变量 1
      • 打印推导式作用域中的变量 2
      • 类外使用列表推导式的例子
    • 结论

提出问题

在执行以下代码定义类时

class A:
    a = 42
    b = list(a + i for i in range(10))

    print(b)

报错

NameError: name 'a' is not defined

以下代码同样报错

class A:
    a = 42
    b = [a + i for i in range(10)]

    print(b)

但以下代码不会报错

a = 9
class A:
    a = 42
    b = list(a + i for i in range(10))

    print(b)

且有以下输出(该结果为类定义时的输出)

[9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

问题分析

  1. 类属性的定义
    在类定义中,a 是一个类属性,值为 42。
  2. 列表推导式的作用域
    列表推导式 list(a + i for i in range(10)) 在执行时,会尝试访问变量 a。然而,列表推导式有自己的局部作用域,它不会直接访问类定义中的变量 a。
  3. 作用域冲突
    在 Python 中,列表推导式的作用域规则是:
  • 列表推导式有自己的局部作用域。
  • 它可以访问外部作用域中的变量,但不会直接访问类定义中的变量。

验证

打印推导式作用域中的变量 1

class A:
    a = 42
    b = [print(locals(), globals()) for i in range(10)]

    print(b)

输出为

{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 0} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 1} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 2} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 3} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 4} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 5} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 6} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 7} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 8} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
{'.0': <range_iterator object at 0x000001B060C71A50>, 'i': 9} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B060C96CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None}
[None, None, None, None, None, None, None, None, None, None]

可以看到可访问的变量中没有a

打印推导式作用域中的变量 2

a = 9
class A:
    a = 42
    b = [print(locals(), globals()) for i in range(10)]

    print(b)

输出为

{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 0} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 1} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 2} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 3} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 4} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 5} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 6} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 7} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 8} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
{'.0': <range_iterator object at 0x000001CB73A18BD0>, 'i': 9} {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CB738B6CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\PycharmProjects\\exam\\exam\\250319\\code1.py', '__cached__': None, 'a': 9}
[None, None, None, None, None, None, None, None, None, None]

可以看到可访问的变量中有a,且其值为全局变量a的值。

所以这种情况下列表推导式可以正常创建列表

a = 9
class A:
    a = 42
    b = [a+i for i in range(10)]

    print(b)

输出为

[9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

类外使用列表推导式的例子

a = 9
b = list(print(locals(), globals()) for i in range(10))
print(b)

输出为

[9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

结论

在Python 3中,生成器表达式和列表推导式在类作用域中的行为可能不会自动捕获类属性,因为它们是在嵌套作用域中运行的。

例如,在类定义中,当在类似列表推导或生成器表达式中引用类变量时,这些表达式实际上是在新的作用域中被评估的。
由于类的作用域不会被隐式地传递到内部的函数或生成器中,这可能导致变量无法找到的情况。也就是说,生成器表达式中的a可能无法访问到类属性a,从而导致NameError。

因此,当列表推导式尝试访问 a 时,它会抛出 NameError,因为 a 不在列表推导式的局部作用域中,也不在全局作用域中。

相关文章:

  • Oracle 23ai Vector Search 系列之2 ONNX(Open Neural Network Exchange)
  • Webpack 配置详解:从入门到实战
  • 复习MySQL20250327
  • OmniPlan Pro for Mac 项目管理流程
  • 人工智能模型的自我学习能力
  • 相对位置2d矩阵和kron运算的思考
  • 各种响应的理解
  • Java学习打卡-Day22-多线程
  • Dify 服务器部署指南
  • SpringBean模块(二)bean初始化(2)和容器初始化顺序的比较--引入ApplicationContextInitializer
  • SQLark SQL编辑器秘籍,编写高效SQL查询
  • SpringBoot3解决跨域请求问题(同源策略、JSONP、CORS策略)(Access-Control-Allow-Origin)(2025详细教程)
  • 电销行业机器人外呼话术设计:关键注意事项与实践指南
  • C语言之数据结构:双向链表
  • 整理一些php7 新特性
  • Node.js 模块加载机制--详解
  • 【设计模式】策略模式+门面模式设计对接银行接口的API
  • # 线性代数:660习题总结660# 宋浩讲解视频
  • [Lc18_拓扑排序] string+queue+map | 火星字典
  • Stable Diffusion vue本地api接口对接,模型切换, ai功能集成开源项目 ollama-chat-ui-vue
  • 广东省原省长卢瑞华逝世,享年88岁
  • 夜读|尊重生命的棱角
  • 继71路之后,上海中心城区将迎来第二条中运量公交
  • 长三角议事厅·周报|从模速空间看上海街区化AI孵化模式
  • 波兰关闭俄罗斯驻克拉科夫领事馆
  • 河南洛阳新安县煤渣倾倒耕地:多年难恢复,为何至今未解决?