从构造函数中取消对类的修改时出错

时间:2014-02-24 18:00:10

标签: python pickle

我想实现一个类(理想情况下是一个单例),在初始化阶段应该使用cPickle机制恢复状态。为此,我编写了以下代码段:

import cPickle
import collections

class Test(collections.OrderedDict):

    path = "test.cp"

    def __init__(self):

        self.path = "test.cp"

        collections.OrderedDict.__init__(self)
        try:
            f = open(Test.path,"rb")
        except IOError:
            return
        else:
            ud = cPickle.load(f)
            self.update(ud)
            f.close()

    def save(self):

        f = open(Test.path,"wb")
        cPickle.dump(self,f)
        f.close()

if __name__ == "__main__":
    t = Test()
    t.save()
    t1 = Test()

运行该代码段会产生以下错误:

    Traceback (most recent call last):
  File "C:\Documents and Settings\pellegrini\Bureau\test.py", line 31, in <module>
    t1 = Test()
  File "C:\Documents and Settings\pellegrini\Bureau\test.py", line 18, in __init__
    ud = cPickle.load(f)
TypeError: ('__init__() takes exactly 1 argument (2 given)', <class '__main__.Test'>, ([],))

dict而不是collections.OrderedDict继承此功能时。从其他类似的帖子来看,这可能与__reduce__方法有关,但我不明白为什么以及怎么做?

您对如何解决此问题有任何想法吗?

非常感谢

埃里克

1 个答案:

答案 0 :(得分:3)

我猜OrderedDict有自己的序列化方式。

def __init__(self, *args):

    self.path = "test.cp"

    collections.OrderedDict.__init__(self, *args)

尝试这个并且你得到一个递归问题,因为pickle使用__init__

无错解决方案是:

import cPickle
import collections

class Test(collections.OrderedDict):

    path = "test.cp"

    def __init__(self, *args):

        self.path = "test.cp"

        collections.OrderedDict.__init__(self, *args)
        if not args:
            try:
                f = open(Test.path,"rb")
            except IOError:
                return
            else:
                ud = cPickle.load(f)
                self.update(ud)
                f.close()

    def save(self):

        with open(Test.path,"wb") as f:
            cPickle.dump(self,f)

if __name__ == "__main__":
    t = Test()
    t.save()
    t1 = Test()

<强>的Singleton

import pickle
import collections

_Test_singleton = None

class Test(collections.OrderedDict):

    path = "test.cp"

    def __new__(self, *args, **kw):
        global _Test_singleton
        if _Test_singleton is not None:
            return _Test_singleton
        _Test_singleton = collections.OrderedDict.__new__(self, *args, **kw)
        _Test_singleton.load()
        return _Test_singleton

    def __init__(self, *args):
        collections.OrderedDict.__init__(self, *args)

    def load(self):
        try:
            f = open(self.path,"rb")
        except IOError:
            return
        else:
            try:
                ud = pickle.load(f)
            finally:
                f.close()
            self.update(ud)

    def save(self):
        with open(self.path,"wb") as f:
            pickle.dump(self,f)


if __name__ == "__main__":
    t = Test()
    t.save()
    t1 = Test()
    assert t is t1