我构建了一个collections.OrderedDict标准类的子类。当我试图解开这个类的一个对象时,我会得到以下错误:
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的范围,以获得以下最小的代码,这些代码触发了预先格式化的错误。下面是:
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()在这一点上,我真的不明白哪里出了问题。我对泡菜机制有什么误解,还是与OrderedDict有关?
非常感谢你的帮助
发布于 2014-03-27 14:45:51
您没有仔细阅读__reduce__的文档:
当返回一个元组时,它必须是2到5个元素的长度。可以省略可选元素,也可以提供
None作为它们的值。此元组的内容按正常方式进行腌制,并用于在未拾取时重构对象。每个元素的语义如下:
您将类作为可调用元素返回,并且作为第二个元素返回items,因此unpickle试图将items传递给类,从而调用__init__,但是__init__不接受任何参数,因此会得到一个错误。
您必须要么更改__init__以接受参数,要么避免将其作为第二个元素,取而代之的是空元组。
https://stackoverflow.com/questions/22690729
复制相似问题