【问题标题】:pickle a dictionary where it's values are of some custom class腌制一个字典,它的值是一些自定义类
【发布时间】:2012-11-16 15:11:42
【问题描述】:

是时候在这里提出我的第一个问题了。 我面临以下问题:

我正在使用 pickle 模块转储一个大字典,然后将其从磁盘加载回来。 问题是解封后两个对象不一样。 其实这就是我正在做的:

在文件A.py 中,我定义了具有一些属性和方法的类。

在文件B.py 中,我创建了一个字典,其中的值是A.py 中类的实例

也在文件B.py 中我腌制了这本字典并再次取消腌制。

这两个字典不一样。我检查了钥匙,都是一样的。问题在于价值观。

有什么想法吗?

【问题讨论】:

  • 实例通常是可腌制的,所以我们需要一些代码示例,或者显示您输入和输出的示例。
  • 这两个字典不一样。 - 用什么来衡量“相同”?他们不会有相同的身份。自定义类是否有__eq__ 方法?

标签: python pickle


【解决方案1】:

具有相同键和值的两个不同字典不会被视为相同:

>>> d1 = {'k1': 12345}
>>> d2 = {'k1': 12345}
>>> d1 is d2
False
>>> d1['k1'] is d2['k1']
False

即使您实际上将值从一个复制到另一个:

>>> d1['k1'] = d2['k1']
>>> d1['k1'] is d2['k1']
True
>>> d1 is d2
False

那是因为每个都是一个单独的容器。另一方面,您可以使用如下表达式检查所有键和值是否具有 相等 值,而不是字面上是相同的对象:

(set(d1) == set(d2)) and all(d1[k] == d2[k] for k in d1)

第一个子表达式确保每个键具有相同的值,第二个子表达式确保与每个键关联的值相等。

当您从保存的数据中重构字典时,会创建一个新字典。它不会是同一个字典,但它的所有键和值都应该与原始字典相同。如果确实不是这样,请至少向我们提供您用来确定它们不同的代码。

【讨论】:

    【解决方案2】:

    实际上是字典值的类的实例如下所示:

    class SchemaObject:
    def __init__(self):
        self.type = ''
        self.name = ''
        self.parentdn = ''
        self.dn = ''
        self.oclass = ''
    
    def initWithXMLNode(self, xmlnode, parentdn):
        self.type = ''
        self.name = ''
        self.parentdn = parentdn
        if xmlnode.nodeName=='fragments':
            self.dn = parentdn
        if xmlnode.nodeName=='fragment':
            self.initFragment(xmlnode)
        elif xmlnode.nodeName=='configGroupLdap':
            self.initGroup(xmlnode)
        elif xmlnode.nodeName=='configObjectLdap':
            self.initObject(xmlnode)
    
    def initWithFragment(self, dn, parentdn, name):
        self.type = 'object'
        self.name = name
        self.parentdn = parentdn
        self.dn = dn
        self.oclass = name
    
    def initFragment(self, xmlnode):
        self.type = 'fragment'
        self.dn = 'fsFragmentId=' + xmlnode.firstChild.nodeValue + ',' + self.parentdn
        self.oclass = 'FSFragment'
    
    def initGroup(self, xmlnode):
        self.type = 'group'
        self.name = 'group-' + xmlnode.getAttribute('name')
        self.dn = xmlnode.getAttribute('dn')
        self.oclass = 'FSFragment'
    
    def initObject(self, xmlnode):
        self.type = 'object'
        self.name = xmlnode.getAttribute('name')
        self.oclass = self.name
        if not xmlnode.hasAttribute('rdnname'):
            self.type = 'no_rdnname'
            return
        else:
            rdnname = xmlnode.getAttribute('rdnname')
        parts = rdnname.split(',')
        if xmlnode.getAttribute('multiple')!='true':
            dn = self.parentdn
            for part in reversed(parts):
                dn = 'fsFragmentId=' + part + ',' + dn
            self.dn = dn
        else:
            self.type = ''
            self.dn = 'fsFragmentId=' + parts[len(parts)-1] + ',' + self.parentdn
            dynamicStatics.append(self.oclass)
    

    在文件 B.py 中,我创建了一个字典,其值基于此类。 字典是 my_dict。 而且我还检查了密钥是否相等。 只有当我尝试比较这些字典之间的两个值时才会失败。

    所以我尝试用以下方法腌制它:

     with open('my_dumped.pkl','wb') as schema:
        pickle.dump(my_dict,schema)
    

    当尝试从磁盘恢复时:

    with open('my_dumped.pkl','rb') as schema:
        b = pickle.load(schema)
    

    如果现在我发出 my_dumped == b 这不应该返回 True 吗?我不关心身份。只是为了平等。正如 marteanu 所说,钥匙都在那里,每个钥匙都有正确的值。

    不幸的是,上面的等式返回 False。

    【讨论】:

      猜你喜欢
      • 2011-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-16
      • 2021-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多