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

Python类方法中self赋值pickle.loads未成功生效问题解决

问题根因

这个问题和pickle.dumps/pickle.loads的序列化反序列化逻辑无关,是Python变量赋值的基础机制导致的:

  • 类实例方法里的self本质是一个局部变量,调用方法时它初始指向传入的实例对象
  • 你在方法内写self = pickle.loads(pickle_data),只是修改了这个局部变量的指向,让它指向反序列化生成的新对象,完全没有改动外部提前创建的b实例的任何属性
  • 你在方法内打印的正确_data_dict值,实际是那个临时生成的反序列化对象的属性,和外部的b实例没有任何关系。方法执行结束后这个局部变量就被回收,外部的b还是一开始执行A(2)创建的实例,它的_data_dict从初始化开始就是空字典,自然打印结果不符合预期。
解决方案

提供两种可直接运行的正确实现方式:

方案1:直接接收反序列化返回的实例(推荐)

pickle.loads本身就会返回完整的反序列化对象,不需要提前创建空实例再在方法内赋值,直接接收返回值即可:

import pickle


class A():
    def __init__(self, nid):
        self.nid = nid
        self._data_dict = {}

    def initData(self, nid, pickle_data=None):
        if nid == 2:
            print("use pickle")
            return pickle.loads(pickle_data)
        else:
            print("normal")
            self._data_dict['key'] = 1
            return self


if __name__ == '__main__':
    a = A(1)
    a.initData(1)
    print(f"a _data_dict::{a._data_dict}")
    pickle_data = pickle.dumps(a, 0)

    print('-'*100)
    b = A(2).initData(2, pickle_data)
    print(f"b _data_dict::{b._data_dict}")

方案2:必须保留提前创建实例逻辑时,拷贝属性到当前实例

如果业务要求必须先创建b实例再调用初始化方法,不要直接替换self,而是把反序列化对象的所有属性更新到当前实例上:

import pickle


class A():
    def __init__(self, nid):
        self.nid = nid
        self._data_dict = {}

    def initData(self, nid, pickle_data=None):
        if nid == 2:
            print("use pickle")
            load_obj = pickle.loads(pickle_data)
            # 将反序列化对象的属性同步到当前实例
            self.__dict__.update(load_obj.__dict__)
            print(f"pickle loads _data_dict:{self._data_dict}")
        else:
            print("normal")
            self._data_dict['key'] = 1


if __name__ == '__main__':
    a = A(1)
    a.initData(1)
    print(f"a _data_dict::{a._data_dict}")
    pickle_data = pickle.dumps(a, 0)

    print('-'*100)
    b = A(2)
    b.initData(2, pickle_data)
    print(f"b _data_dict::{b._data_dict}")
运行结果

两种方案修改后输出均符合预期:

normal
a _data_dict::{'key': 1}
----------------------------------------------------------------------------------------------------
use pickle
pickle loads _data_dict:{'key': 1}
b _data_dict::{'key': 1}

内容的提问来源于stack exchange,提问作者xin.chen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:18:21