Python:(un-)pickle基于dict的树时的模糊性

时间:2013-05-17 15:29:58

标签: python dictionary tree pickle

我有一个简单的树结构,其中每个节点可以有几个通过密钥访问的子节点(+ value中存储的一些有效负载):

class NodeDict(dict):
  def __init__(self, parent):
    self.parent = parent
    self.value = None
  def AddChild(self, label):
    self[label] = NodeDict(self)
    return self[label]

class TreeDict:
  def __init__(self):
    self.root = NodeDict(None)
  def ToString(self, level, node):
    res = ":" + str(node.value) + "\n"
    for k, v in node.items():
      res += "  "*level + str(k) + self.ToString(level + 1, v)
    return res
  def __str__(self):
    return self.ToString(1, self.root)

当我尝试腌制这样一棵树时,我遇到的问题是它没有正确地打开,如下例所示:

class Obj:
  def __init__(self, v):
    self.v = v
  def __str__(self):
    return str(self.v)

t = TreeDict()
a = t.root.AddChild(Obj("A"))
b = a.AddChild(Obj("B"))
c = b.AddChild(Obj("C"))
d = b.AddChild(Obj("D"))
e = a.AddChild(Obj("E"))

print t

import cPickle
cPickle.dump(t,  open("test.dat", "w"))
t = cPickle.load(open("test.dat", "r"))
print t

树在

之前看起来像这样
:None
  A:None
    E:None
    B:None
      C:None
      D:None

并且经过酸洗和去除后如此:

:None
  A:None
    B:None
      B:None
        D:None
        C:None
      E:None
    E:None

问题产生于我在树中使用Obj作为label s(即dict中的键)。 (如果它们并非全部相互不同,那么在使用例如字符串而不是Obj时也会失败。)

如何将其更改为按预期工作?

2 个答案:

答案 0 :(得分:1)

在对dict等内置类型进行子类化或使用新样式类时,至少应使用pickle protocol 2。 python2的默认值仍为0,这可能会出现问题。

使用dump(t, open("test.dat", "wb"), protocol=2)时,您的代码可以与cPicklepickle一起使用。

请记住remark about opening the files in binary mode

答案 1 :(得分:0)

如果这仍然不起作用(参见Aya的评论),是否正在使用另一种树形结构作为选项?如果是,则这是一个脚本to pickle DOM tree structure