Python Pickle使用Pickler时出现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: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

最新更新