【问题标题】:pickling an OrderedDict-derived object酸洗一个 OrderedDict 派生的对象
【发布时间】:2014-03-27 14:32:07
【问题描述】:

我构建了 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()

在这一点上,我真的不明白那里出了什么问题。我对泡菜机制有什么误解还是与 OrderedDict 相关的一些问题?

非常感谢您的帮助

【问题讨论】:

    标签: python ordereddictionary


    【解决方案1】:

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

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

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

    您将类返回为可调用类,并将 items 作为第二个元素返回,因此 unpickle 试图将 items 传递给类,从而调用 __init__,但您的 __init__ 不接受任何参数并且因此你得到一个错误。

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

    【讨论】:

    • 非常感谢!老实说,我把这部分读了好几遍,但并没有真正理解它。有了你的回答,现在肯定更清楚了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 2010-12-30
    • 1970-01-01
    • 2019-06-19
    • 1970-01-01
    相关资源
    最近更新 更多