You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何从Python模块导入类时会执行模块内的类对象列表实例化代码?

问题原因

Python 的模块导入机制设计如此:无论你使用 import module 还是 from module import xxx 语法导入模块内容,都会完整执行目标模块的所有顶层代码,类定义、顶层变量赋值都属于顶层代码,因此你写在模块最外层的 LIST_OF_A = [ A(2,3), B(4,5) ] 会在导入时自动执行,完成列表和内部类实例的创建。

注:你给出的示例代码本身存在几处语法错误,修复后才能正常运行:

  • 数据类的导入应为 import dataclasses,装饰器为 @dataclasses.dataclass
  • big_method 里访问属性要写 self.x、self.y
  • 列表里的 B(4,5) 如果没有提前定义类B,导入时会直接抛出 NameError
同文件保留两个内容的解决方案

分两种场景处理:

场景1:LIST_OF_A 仅在模块自身作为脚本运行时使用,不需要对外导出

把 LIST_OF_A 相关的代码放到 if __name__ == "__main__" 判断块内即可,导入模块时该块内的代码不会执行:

import dataclasses

@dataclasses.dataclass
class A:
  x: int
  y: int

  def big_method(self):
      do_big_stuff(self.x, self.y)

if __name__ == "__main__":
    # 仅当直接运行python module.py时才会执行下面的代码
    LIST_OF_A = [ A(2,3), A(4,5) ]
    # 你原本要执行的其他脚本逻辑

场景2:LIST_OF_A 需要对外导出,供其他导入该模块的代码使用

可以用懒加载的方式避免导入时就实例化:

方法1:用函数封装获取逻辑

# 其他类定义不变
_LIST_OF_A = None

def get_list_of_a():
    global _LIST_OF_A
    if _LIST_OF_A is None:
        _LIST_OF_A = [ A(2,3), A(4,5) ]
    return _LIST_OF_A

其他模块使用时调用 module.get_list_of_a() 即可,只有第一次调用时才会完成实例化。

方法2:Python 3.7+ 用模块级__getattr__实现懒加载

在module.py末尾添加:

def __getattr__(name):
    if name == "LIST_OF_A":
        return [ A(2,3), A(4,5) ]
    raise AttributeError(f"module {__name__} has no attribute {name}")

其他模块可以正常用 from module import LIST_OF_A 或者 module.LIST_OF_A 访问,只有第一次访问时才会实例化。

内容的提问来源于stack exchange,提问作者mrkgoh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:36:03