我有一个简单的树结构,其中每个节点可以有几个通过密钥访问的子节点(+ 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
时也会失败。)
如何将其更改为按预期工作?
答案 0 :(得分:1)
在对dict
等内置类型进行子类化或使用新样式类时,至少应使用pickle protocol 2。 python2的默认值仍为0,这可能会出现问题。
使用dump(t, open("test.dat", "wb"), protocol=2)
时,您的代码可以与cPickle
和pickle
一起使用。
答案 1 :(得分:0)
如果这仍然不起作用(参见Aya的评论),是否正在使用另一种树形结构作为选项?如果是,则这是一个脚本to pickle DOM tree structure。