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

Python中Test类被重复加载入内存的原因咨询

为什么Test类被加载了两次?

问题场景

有以下两个Python文件,执行module1.py后,"return new object"被打印了两次,且Test类出现了两个不同的id,与预期的仅加载一次不符。

module1.py 代码

class Test:
    data=None

    def get_data():
        if Test.data is not None:
            print("return existing object")
            return Test.data 
        else:
            Test.data="abc"
            print("return new object")
            return Test.data

import module2
print("1:",Test.get_data(), "id:", id(Test))
print("2:",Test.get_data(), "id:", id(Test))

module2.py 代码

from module1 import Test
print("3:",Test.get_data(), "id:", id(Test))

执行python module1.py后的输出

return new object
1: abc id: 2168979056288
return existing object  
2: abc id: 2168979056288
return existing object  
3: abc id: 2168979056288
return new object       
1: abc id: 2168978913056
return existing object  
2: abc id: 2168978913056

原因解释

这是Python模块加载机制的特性导致的,核心逻辑如下:

  1. 第一次加载:作为__main__模块
    当你直接运行module1.py时,Python会将其标记为__main__模块加载,此时会创建第一个Test类对象(对应输出中的第一个id)。

  2. 第二次加载:作为普通模块被导入
    当module1.py执行到import module2时,module2.py会被加载,其中的from module1 import Test语句会触发Python加载名为module1的普通模块。由于此时sys.modules中只有__main__,没有module1这个模块实例,Python会重新读取module1.py的代码,创建第二个完全独立的Test类对象(对应输出中的第二个id)。

  3. 两次加载的模块是独立实体
    Python中,__main__模块和同名的普通模块(如module1)是两个完全分开的模块实例,它们的全局命名空间、类对象、变量都是独立的。因此第二次加载时,新的Test类的data初始值为None,自然会再次触发"return new object"的打印。

  4. 完整执行流程对应输出

    • 第一步:__main__模块(module1.py)定义第一个Test类,执行import module2;
    • 第二步:加载module2.py,触发加载module1普通模块,该模块定义第二个Test类,执行自身的print语句(对应输出中后三行的return new object、1:、2:);
    • 第三步:module2拿到第二个Test类,调用get_data()(此时data已被设置为abc,打印return existing object和3:);
    • 第四步:回到__main__模块,执行自身的print语句,调用第一个Test类的get_data()(此时data还是None,打印return new object和1:、2:)。

解决方案

方案1:隔离脚本执行代码

在module1.py中加入if __name__ == "__main__"判断,让顶层打印代码仅在直接运行时执行,避免模块被导入时重复执行:

class Test:
    data=None

    def get_data():
        if Test.data is not None:
            print("return existing object")
            return Test.data 
        else:
            Test.data="abc"
            print("return new object")
            return Test.data

import module2

if __name__ == "__main__":
    print("1:",Test.get_data(), "id:", id(Test))
    print("2:",Test.get_data(), "id:", id(Test))

方案2:使用独立入口脚本

创建单独的入口文件(如main.py),避免module1既作为__main__又作为普通模块被加载:

# main.py
import module1

运行python main.py,此时module1只会被加载一次作为普通模块,Test类仅创建一次,"return new object"仅打印一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 00:08:11