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

pickle加载序列化对象后类属性实例值丢失的原因解析

Pickle序列化后predict返回None的核心原因解析

场景与代码说明

假设存在四个文件:main_class.py、help_class.py、train.py和predict.py,代码分别如下:

main_class.py

from help_class import HC

class MC:
    hc = HC()

    def fit(self):
        self.hc.fit()

    def predict(self):
        return self.hc.predict()

help_class.py

class HC:
    instances = None

    def fit(self):
        self.instances = "fitted"

    def predict(self):
        return self.instances

train.py

# train.py
from main_class import MC
import pickle

mc = MC()
mc.predict() # 返回 None
mc.fit()
mc.predict() # 返回 "fitted" 

with open("./mc_fitted.pkl","wb") as f:
    pickle.dump(mc,f)

predict.py

# predict.py
import pickle

with open("./mc_fitted.pkl","rb") as f:
    mc = pickle.load(f)

mc.predict() # 返回 None,不符合预期

核心原因解析

  • Pickle的序列化范围限制:Pickle只序列化对象的实例属性,以及重建对象所需的类元信息(类名、所属模块),类级别的属性不会被写入序列化文件。
  • MC类中hc的属性性质:MC里的hc = HC()是类属性,属于MC类本身,不是某个MC实例独有的。在train.py中调用mc.fit()时,实际修改的是这个类属性对应的HC实例的取值,但这个类属性本身不会被Pickle序列化。
  • 反序列化的重建逻辑:在predict.py加载pickle文件时,Python会先导入MC类(此时MC类的类属性hc会被重新初始化,生成一个全新的HC实例,其instances是类属性默认的None),然后基于序列化时保存的MC实例属性(这里MC实例没有自定义实例属性,所以只是一个空的MC实例)完成重建。此时mc.hc指向的是新创建的HC实例,而非train.py中被修改过的那个。
  • HC类中instances的属性覆盖细节:HC类的instances原本是类属性,但self.instances = "fitted"会给HC实例创建一个同名的实例属性,临时覆盖类属性的取值。但由于MC的hc是类属性未被序列化,反序列化后新的HC实例没有这个实例属性,调用predict()时会读取HC类的instances类属性,返回None。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:32:28