腌制OrderedDict派生的对象

时间:2014-03-27 14:32:07

标签: python ordereddictionary

我构建了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相关的麻烦?

非常感谢你的帮助

1 个答案:

答案 0 :(得分:3)

您没有仔细阅读__reduce__的文档:

  

返回元组时,它必须介于2到5个元素之间   长。可以省略可选元素,也可以提供None   作为他们的价值。这个元组的内容正常腌制   用于在unpickling时重建对象。的语义   每个元素都是:

     
      
  • 将调用以创建对象初始版本的可调用对象。 元组的下一个元素将提供   此可调用的参数,以及后来的元素提供了额外的参数   随后将用于完全重建的状态信息   腌制数据。
  •   

您将该类作为可调用方式返回,并将第二个元素作为items返回,因此unpickle正在尝试将items传递给类,从而调用__init__,但是您的__init__没有任何参数,因此你得到一个错误。

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