我想实现一个类(理想情况下是一个单例),在初始化阶段应该使用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__
方法有关,但我不明白为什么以及怎么做?
您对如何解决此问题有任何想法吗?
非常感谢
埃里克
答案 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