【问题标题】:Pickle dictionary with object value deserialises with different value具有对象值的泡菜字典反序列化具有不同的值
【发布时间】:2019-08-19 09:43:55
【问题描述】:

我有一本字典,其中一个值是一个对象。我正在尝试使用Pickle 模块对这个字典进行序列化和反序列化,如下所示:

import pickle

class ExampleClass(object):
    def __init__(self, obj_id, name, type):
        self.obj_id = obj_id
        self.name = name
        self.type = 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) # expected to be True

这给出了以下输出:

{'object': <__main__.ExampleClass object at 0x000001D726852148>, 'date': '02041980', 'event': 'test'}
{'object': <__main__.ExampleClass object at 0x000001D7268527C8>, 'date': '02041980', 'event': 'test'}
False

dict 的对象值'object': my_obj 不同,我不明白为什么会这样。

任何使这个example_dictpickle 与其对应的重构值相同的建议或信息都会非常有用。

【问题讨论】:

  • 有两个事实。一种是如果您不指定equality,则实例使用地址来识别相等性。另一种是,恢复的实例是另一个实例,但不是原始实例。基于这两个事实,example_dict == reconstituted 返回False 是合理的,因为尽管这两个实例包含相同的内容,但它们仍然是两个不同的实例。

标签: python python-3.x dictionary object pickle


【解决方案1】:

@Straw 的评论指出了正确的方向。

如果其他人可能发现自己处于类似情况,则需要根据对象实例的属性 as described here 比较对象实例是否相等。

对于本故事中的示例,实现 __eq__ 方法将允许比较对象实例:

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 NotImplemented

        return self.obj_id == other.obj_id and self.name == other.name and self.type == other.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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2022-12-15
    • 2014-05-24
    • 1970-01-01
    • 2019-12-29
    相关资源
    最近更新 更多