2014-03-27 56 views
1

我构建了collections.OrderedDict标准类的子类。当我尝试unpickle这个班,我得到以下错误的对象:酸洗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的身体得到以下最低代码触发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有关的麻烦?

非常感谢您的帮助

回答

3

你没看过的文档__reduce__不够仔细:

When a tuple is returned, it must be between two and five elements long. Optional elements can either be omitted, or None can be provided as their value. The contents of this tuple are pickled as normal and used to reconstruct the object at unpickling time. The semantics of each element are:

  • A callable object that will be called to create the initial version of the object. The next element of the tuple will provide arguments for this callable, and later elements provide additional state information that will subsequently be used to fully reconstruct the pickled data.

要退回类的调用和第二个元素items因此unpickle是试图通过items到类,因此呼吁__init__,但您的__init__不采取任何论点,因此你会得到一个错误。

您必须更改__init__以接受参数或避免将其作为第二个元素,而是将其替换为空元组。

+1

非常感谢!为了真诚,我多次阅读本节,但没有真正理解它。随着你的回答,它现在更清晰了。 – Eurydice