使用Pickler时出现Python Pickle EOFError(但使用pickle.dump()时没有)
我在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:\Users\user\pickletest2.py", line 13, in <module>
tup = pickle.load(g)
File "C:\Python26\lib\pickle.py", line 1370, in load
return Unpickler(file).load()
File "C:\Python26\lib\pickle.py", line 858, in load
dispatch[key](self)
File "C:\Python26\lib\pickle.py", line 880, in load_eof
raise EOFError
EOFError
不过,如果我用pickle.dump()而不是使用Pickler对象,代码就能正常工作了。我之所以想用Pickler,是因为我想对每个对象进行一些操作,然后再进行保存。
有没有人知道为什么我的代码会这样?我查了一下,发现没有使用'wb'和'rb'模式通常会导致这个问题,还有就是没有调用f.close(),但我这两者都有。使用-1作为协议会有问题吗?我想保留这个设置,因为它可以处理那些定义了__slots__
方法但没有定义__getstate__
方法的对象。
2 个回答
1
一般来说,使用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
2
Pickler.save()
是一个比较底层的方法,通常不建议直接调用它。
如果你用 p.dump(saveobj)
来代替 p.save(saveobj)
,它就会按预期工作。
也许应该把它叫做 _save
,这样就不会让人困惑了。不过 dump
是文档中描述的方法,而且它和模块级别的 pickle.dump
很好地对应起来。