我有以下代码片段:
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
我究竟做错了什么?
除非您有拼写错误,否则问题可能出在这一行,您selffp
不会将文件句柄分配给self.fp
:
selffp=file("detailing.dat","rb")
如果这是一个拼写错误,并且您的代码实际打开了该文件self.fp
,那么您可能希望验证该文件实际上有内容(即:前一个pickle工作)...错误表明该文件为空.
编辑:在这个答案的评论中,S.Lott有一个很好的总结,为什么拼写错误产生了你看到的错误,我在这里粘贴答案的完整性:"selffp将是未使用的打开文件,以及self.fp (旧的关闭文件)将用于加载".
这是我建议使用的版本:
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上有一个拼写错误.但是,我注意到其他一些可能导致问题的事情.
首先,您不应该直接使用文件构造函数.您应该使用内置的open函数.
其次,你应该避免在finally块之外调用文件的close方法.在这种情况下,我使用了python 2.6和块.您可以使用以下命令在Python 2.5中使用它:
from __future__ import with_statement
如果在任何地方抛出异常,这将阻止文件被卡住(因为它会在退出with块时关闭文件).虽然这不是导致问题的原因,但要记住这一点很重要,因为如果其中一个文件对象的方法抛出异常,该文件将无限期地在sys.traceback中保持打开状态.
(请注意,你应该接受Jarret Hardie的回答,他抓住了这个bug :-))