为什么我会读取"Pickle - EOFError:Ran out of input"读取空文件?

Mag*_*gix 79 python file pickle

我在尝试使用时遇到了一个有趣的错误Unpickler.load(),这里是源代码:

open(target, 'a').close()
scores = {};
with open(target, "rb") as file:
    unpickler = pickle.Unpickler(file);
    scores = unpickler.load();
    if not isinstance(scores, dict):
        scores = {};
Run Code Online (Sandbox Code Playgroud)

这是追溯:

Traceback (most recent call last):
File "G:\python\pendu\user_test.py", line 3, in <module>:
    save_user_points("Magix", 30);
File "G:\python\pendu\user.py", line 22, in save_user_points:
    scores = unpickler.load();
EOFError: Ran out of input
Run Code Online (Sandbox Code Playgroud)

我想读的文件是空的.如何避免出现此错误,并获取空变量?

Pad*_*ham 90

我先检查文件是不是空的:

import os

scores = {} # scores is an empty dict already

if os.path.getsize(target) > 0:      
    with open(target, "rb") as f:
        unpickler = pickle.Unpickler(f)
        # if file is not empty scores will be equal
        # to the value unpickled
        scores = unpickler.load()
Run Code Online (Sandbox Code Playgroud)

open(target, 'a').close()您的代码中也没有任何操作,您也不需要使用;.

  • 捕获“ EOF异常”将无法使您摆脱所有其他潜在的错误。 (2认同)
  • 您也可以使用 os 模块检查文件是否存在,这可能比每次打开和关闭文件更好。 (2认同)

Abh*_*nan 86

这里的大多数答案都涉及如何管理EOFError异常,如果您不确定是否为空,那么这是非常方便的.

但是,如果您对pickle文件为空感到惊讶,可能是因为您通过'wb'或其他可能覆盖该文件的模式打开了文件名.

例如:

filename = 'cd.pkl'
with open(filename, 'wb') as f:
    classification_dict = pickle.load(f)
Run Code Online (Sandbox Code Playgroud)

这将覆盖pickle文件.您可能在使用之前错误地完成了此操作:

...
open(filename, 'rb') as f:
Run Code Online (Sandbox Code Playgroud)

然后获得了EOFError,因为前面的代码块覆盖了cd.pkl文件.

在Jupyter或控制台(Spyder)中工作时,我通常会在读/写代码上写一个包装器,然后调用包装器.这样可以避免常见的读写错误,如果您要通过艰难的程度多次读取同一个文件,可以节省一些时间

  • `但是,如果你对pickle文件是空的感到惊讶,那可能是因为你通过'wb'或其他一些可能覆盖文件的模式打开了文件名.这让你赢了+1 (23认同)
  • 我这样做了; 非常感谢这个笔记(我很高兴我不是唯一一个!) (7认同)
  • 今天,男人经历了同样的事情,当我真正打算阅读它时,用“wb”打开了一个泡菜;(还有回去吗? (5认同)
  • [文件锁定必要性](/sf/answers/718460151/) - 这个答案会对很多人有帮助,我试图在文件打开写入时读取该文件。 (4认同)
  • 之前也用“ wb”覆盖了它。+1 (3认同)
  • 有时显而易见的东西根本不明显!谢谢 :) (2认同)

use*_*494 17

腌制文件很可能是空的。

如果您正在复制和粘贴代码,覆盖pickle 文件非常容易。

例如下面写了一个pickle文件:

pickle.dump(df,open('df.p','wb'))
Run Code Online (Sandbox Code Playgroud)

如果您复制此代码以重新打开它,但忘记更改'wb'为,'rb'那么您将覆盖该文件:

df=pickle.load(open('df.p','wb'))
Run Code Online (Sandbox Code Playgroud)

正确的语法是

df=pickle.load(open('df.p','rb'))
Run Code Online (Sandbox Code Playgroud)


Amr*_*man 9

如您所见,这实际上是一个自然错误..

从 Unpickler 对象读取的典型构造是这样的..

try:
    data = unpickler.load()
except EOFError:
    data = list()  # or whatever you want
Run Code Online (Sandbox Code Playgroud)

EOFError 只是引发了,因为它正在读取一个空文件,它只是意味着文件结束..


小智 5

有同样的问题。事实证明,当我写入 pickle 文件时,我没有使用 file.close()。插入该行,错误就消失了。