所以,我试图在Windows 7上使用Python的pickle保存一些对象到磁盘。我使用下面的代码,它在几乎任意对象上都失败了(saveobj的内容并不重要,它无论如何都会失败)。我的测试代码如下:
import pickle, os, time
outfile = "foo.pickle"
f = open(outfile, 'wb')
p = pickle.Pickler(f, -1)
saveobj = ( 2,3,4,5,["hat", {"mat": 6}])
p.save(saveobj)
#pickle.dump(saveobj, f)
print "done pickling"
f.close()
g = open(outfile, 'rb')
tup = pickle.load(g)
g.close()
print tup
当我运行它时,我得到以下输出/错误:
done pickling
Traceback (most recent call last):
File "C:Usersuserpickletest2.py", line 13, in <module>
tup = pickle.load(g)
File "C:Python26libpickle.py", line 1370, in load
return Unpickler(file).load()
File "C:Python26libpickle.py", line 858, in load
dispatch[key](self)
File "C:Python26libpickle.py", line 880, in load_eof
raise EOFError
EOFError
但是,如果我使用pickle.dump()而不是Pickler对象,它工作得很好。我使用Pickler的原因是我想把它子类化,这样我就可以在pickle它之前对每个对象执行操作。
有人知道为什么我的代码这样做吗?我的搜索显示,没有'wb'和'rb'通常会导致这种情况,因为没有f.k close(),但我有这两个。使用-1作为协议有问题吗?我想保留它,因为它可以处理那些定义自己的__slots__
方法而不定义__getstate__
方法的对象。
Pickler.save()
是一个较低级别的方法,你不应该直接调用。
如果您调用p.dump(saveobj)
而不是p.save(saveobj)
,它将按预期工作。
也许它应该被称为_save
以避免混淆。但是dump
是文档中描述的方法,它与模块级的pickle.dump
完全匹配。
一般来说,出于性能考虑,最好使用cPickle(因为cPickle是用C编写的)。无论如何,使用dump它工作得很好:
import pickle
import os, time
outfile = "foo.pickle"
f = open(outfile, 'wb')
p = pickle.Pickler(f, -1)
saveobj = ( 2,3,4,5,["hat", {"mat": 6}])
p.dump(saveobj)
#pickle.dump(saveobj, f)
f.close()
print "done pickling"
#f.close()
g = open(outfile, 'rb')
u = pickle.Unpickler(g) #, -1)
tup = u.load()
#tup = pickle.load(g)
g.close()
print tup