简体   繁体   English

腌制OrderedDict派生的对象

[英]pickling an OrderedDict-derived object

I built a subclass of collections.OrderedDict standard class. 我构建了collections.OrderedDict标准类的子类。 When I try to unpickle an object of this class I get the following error: 当我尝试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]],))

Trying to understand the reason for such behaviour I narrowed the body of collections.OrderedDict to get the following minimal code that triggers the aformentionned error. 试图理解这种行为的原因我缩小了collections.OrderedDict的主体,以获得以下触发aformentionned错误的最小代码。 Here it is: 这里是:

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()

At this point, I really do not understand what is going wrong in there. 在这一点上,我真的不明白那里出了什么问题。 Is there something I misunderstood with pickle mechanism or is there some trouble related to OrderedDict ? 有没有我用pickle机制误解的东西,或者是否有一些与OrderedDict相关的麻烦?

thanks a lot for your help 非常感谢你的帮助

You didn't read the documentation for __reduce__ carefully enough: 您没有仔细阅读__reduce__的文档:

When a tuple is returned, it must be between two and five elements long. 返回元组时,它必须长度在2到5个元素之间。 Optional elements can either be omitted, or None can be provided as their value. 可以省略可选元素,或者可以提供None作为其值。 The contents of this tuple are pickled as normal and used to reconstruct the object at unpickling time. 这个元组的内容正常腌制,并用于在unpickling时重建对象。 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. 元组的下一个元素将为此可调用提供参数 ,后面的元素提供其他状态信息,随后将用于完全重建pickle数据。

You are returning the class as callable and as second element the items hence the unpickle is trying to pass the items to the class thus calling __init__ , but your __init__ doesn't take any argument and hence you get an error. 你将类作为callable返回,作为第二个元素返回items因此unpickle试图将items传递给类,从而调用__init__ ,但是你的__init__没有接受任何参数,因此你得到一个错误。

You have to either change the __init__ to accept the argument or avoid putting that as second element and you an empty tuple instead. 您必须更改__init__以接受参数或避免将其作为第二个元素而改为空元组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM