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

Pickle序列化含自定义对象字典后反序列化结果不一致问题

问题原因分析

你遇到的问题根源在于自定义类实例的默认比较逻辑:Python中,自定义类的实例默认是通过**内存地址(身份)**来判断相等性的,也就是is运算符的判断逻辑。反序列化时,pickle会创建一个全新的对象实例,它的内存地址和原对象肯定不一样,所以即使两个实例的属性完全相同,==比较也会返回False,进而导致包含它们的字典比较结果为False。

解决方案:实现自定义的相等性判断

要让序列化前后的字典比较返回True,我们需要给ExampleClass添加__eq__方法,定义两个实例在什么情况下被视为相等(也就是所有属性值完全匹配)。同时,为了遵循Python的最佳实践,建议同时实现__hash__方法(这样实例可以被安全地用作字典键或放入集合中,保证哈希逻辑和相等逻辑的一致性)。

修改后的代码如下:

import pickle

class ExampleClass(object):
    def __init__(self, obj_id, name, type):
        self.obj_id = obj_id
        self.name = name
        self.type = type
    
    def __eq__(self, other):
        # 先判断对方是否为同一类的实例
        if not isinstance(other, ExampleClass):
            return False
        # 比较所有属性的值,全部匹配则视为相等
        return (self.obj_id == other.obj_id and
                self.name == other.name and
                self.type == other.type)
    
    def __hash__(self):
        # 基于实例的属性生成哈希值,和__eq__逻辑保持一致
        return hash((self.obj_id, self.name, self.type))

my_obj = ExampleClass(1, 'tu42', 'bas5')
example_dict = {'object': my_obj, 'date': '02041980', 'event': 'test'}

with open("test.pickle", "wb") as handle:
    pickle.dump(example_dict, handle, protocol=pickle.HIGHEST_PROTOCOL)

with open("test.pickle", "rb") as handle:
    reconstituted = pickle.load(handle)

print(example_dict)
print(reconstituted)
print(example_dict == reconstituted)  # 现在会输出True
print(my_obj is reconstituted['object'])  # 输出False,因为是不同实例,但逻辑相等
运行结果说明

修改后,example_dict == reconstituted会返回True,因为字典会递归比较每个键对应的值:

  • 字符串类型的date和event本身就按值比较,结果相等;
  • 自定义类的实例现在会用我们实现的__eq__方法比较,属性全部匹配就返回True。

而my_obj is reconstituted['object']仍然返回False,这是正常的——反序列化确实创建了新的对象实例,但它们的逻辑状态完全一致,这正是序列化想要达到的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:04:13