我有以下代码片段:
def database(self):
databasename=""
host=""
user=""
password=""
try:
self.fp=file("detailing.dat","rb")
except IOError:
self.fp=file("detailing.dat","wb")
pickle.dump([databasename,host,user,password],self.fp,-1)
self.fp.close()
selffp=file("detailing.dat","rb")
[databasename,host,user,password]=pickle.load(self.fp)
return
它有错误:
Traceback (most recent call last):
File "detailing.py", line 91, in ?
app=myApp()
File "detailing.py", line 20, in __init__
wx.App.__init__(self,redirect,filename,useBestVisual,clearSigInt)
File "/usr/lib64/python2.4/site-packages/wx-2.6-gtk2-unicode/wx/_core.py", line 7473, in __init__
self._BootstrapApp()
File "/usr/lib64/python2.4/site-packages/wx-2.6-gtk2-unicode/wx/_core.py", line 7125, in _BootstrapApp
return _core_.PyApp__BootstrapApp(*args, **kwargs)
File "detailing.py", line 33, in OnInit
self.database()
File "detailing.py", line 87, in database
[databasename,host,user,password]=pickle.load(self.fp)
File "/usr/lib64/python2.4/pickle.py", line 1390, in load
return Unpickler(file).load()
File "/usr/lib64/python2.4/pickle.py", line 872, in load
dispatch[key](self)
File "/usr/lib64/python2.4/pickle.py", line 894, in load_eof
raise EOFError
EOFError
我做错了什么?
答案 0 :(得分:14)
除非您有拼写错误,否则问题可能出在这一行,您将文件句柄分配给selffp
而不是self.fp
:
selffp=file("detailing.dat","rb")
如果这是一个拼写错误,并且您的代码实际上将文件打开到self.fp
,那么您可能希望验证该文件实际上有内容(即:之前的pickle工作)...错误建议该文件为空。
编辑:在对这个答案的评论中,S。Lott有一个很好的总结,为什么拼写错误产生了你看到的错误我在这里粘贴答案的完整性:“selffp将是未使用的打开文件,并且self.fp(旧的关闭文件)将用于加载“。
答案 1 :(得分:5)
以下是我建议使用的版本:
def database(self):
databasename=""
host=""
user=""
password=""
try:
self.fp=open("detailing.dat","rb")
except IOError:
with open("detailing.dat", "wb") as fp:
pickle.dump([databasename,host,user,password],fp,-1)
self.fp=open("detailing.dat","rb")
[databasename,host,user,password]=pickle.load(self.fp)
return
正如已经指出的那样,self.fp上有一个拼写错误。但是,我注意到其他一些可能导致问题的事情。
首先,你shouldn't be using the file constructor directly。您应该使用内置的open函数。
其次,你应该避免在finally块之外调用文件的close方法。在这种情况下,我使用了python 2.6和块。您可以使用以下命令在Python 2.5中使用它:
from __future__ import with_statement
如果在任何地方抛出异常,这将阻止文件被卡住(因为它会在退出with块时关闭文件)。虽然这不是问题的原因,但要记住这一点很重要,因为如果其中一个文件对象的方法抛出异常,该文件将无限期地在sys.traceback中保持打开状态。
(请注意,你应该接受Jarret Hardie的回答,他抓住了这个bug :-))
答案 2 :(得分:1)
当我没有选择正确的模式来读取文件(wb
而不是rb
)时,我收到此错误。改回rb
不足以解决问题。但是,再次生成一个新的干净的pickle文件解决了这个问题。似乎没有选择正确的模式打开二进制文件以某种方式“损坏”文件,然后无论如何都无法打开。
但我是Python的初学者,所以我可能也错过了一些东西。
答案 3 :(得分:0)
虽然这不是对OP问题的直接回答 - 但在尝试使用EOFError
解压缩二进制文件时,我在搜索pickle.load(open(filename, "r"))
的原因时遇到了这个答案。
import cPickle as pickle
A = dict((v, i) for i, v in enumerate(words))
with open("words.pkl", "wb") as f:
pickle.dump(A, f)
#...later open the file -- mistake:trying to read a binary with non-binary method
with open("words.pkl", "r") as f:
A =pickle.load(f) # EOFError
# change that to
with open ("words.pkl", "rb") as f: # notice the "rb" instead of "r"
A = pickle.load(f)