Python Pickle EOFerror使用Pickler时(但不是pickle.dump())

时间:2011-07-07 21:26:47

标签: python serialization pickle

所以,我正在尝试使用Python的pickle将一些对象保存到Windows 7上的磁盘上。我正在使用下面的代码,几乎任何任意对象都失败了(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 个答案:

答案 0 :(得分:2)

Pickler.save()是一种较低级别的方法,您不应该直接调用。

如果您拨打p.dump(saveobj)而不是p.save(saveobj),则会按预期工作。

也许应该将其称为_save以避免混淆。但dump是文档中描述的方法,它与模块级pickle.dump完全匹配。

答案 1 :(得分:1)

一般来说,出于性能原因最好使用cPickle(因为cPickle是用C语言编写的)。 无论如何,使用转储工作正常:

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