我构建了collections.OrderedDict标准类的子类。当我尝试unpickle这个类的对象时,我得到以下错误:
Traceback (most recent call last):
File "pickle.py", line 29, in <module>
print cPickle.load(f)
TypeError: ('__init__() takes exactly 1 argument (2 given)', <class '__main__.ConfiguratorsDict'>, ([['toto', 20]],))
试图理解这种行为的原因我缩小了collections.OrderedDict的主体,以获得以下触发了aformentionned错误的最小代码。这是:
import cPickle
class OrderedDict(dict):
def __reduce__(self):
items = [[k, self[k]] for k in self]
inst_dict = vars(self).copy()
for k in vars(OrderedDict()):
inst_dict.pop(k, None)
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
class ConfiguratorsDict(OrderedDict):
def __init__(self):
OrderedDict.__init__(self)
self._myspec = "blabla"
if __name__ == "__main__":
f = open("test.pickle","wb")
c = ConfiguratorsDict()
c["toto"] = 20
cPickle.dump(c,f)
f.close()
f = open("test.pickle","rb")
print cPickle.load(f)
f.close()
此时,我真的不明白那里出了什么问题。有没有我用pickle机制误解的东西,或者是否有与OrderedDict相关的麻烦?
非常感谢你的帮助
答案 0 :(得分:3)
您没有仔细阅读__reduce__
的文档:
返回元组时,它必须介于2到5个元素之间 长。可以省略可选元素,也可以提供
None
作为他们的价值。这个元组的内容正常腌制 用于在unpickling时重建对象。的语义 每个元素都是:
- 将调用以创建对象初始版本的可调用对象。 元组的下一个元素将提供 此可调用的参数,以及后来的元素提供了额外的参数 随后将用于完全重建的状态信息 腌制数据。
您将该类作为可调用方式返回,并将第二个元素作为items
返回,因此unpickle正在尝试将items
传递给类,从而调用__init__
,但是您的__init__
没有任何参数,因此你得到一个错误。
您必须更改__init__
以接受参数或避免将其作为第二个元素而改为空元组。