web-dev-qa-db-ja.com

空のファイルを読み取る「Pickle-EOFError:Ran out of input」が表示されるのはなぜですか?

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 = {};

トレースバックは次のとおりです。

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

読み込もうとしているファイルは空です。このエラーの発生を回避し、代わりに空の変数を取得するにはどうすればよいですか?

68
Magix

最初にファイルが空でないことを確認します。

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()

また、open(target, 'a').close()はコード内で何も実行していないため、;を使用する必要はありません。

80

ここでの回答のほとんどは、EOFError例外を管理する方法を扱っています。これは、ピクルされたオブジェクトが空かどうかわからない場合に非常に便利です。

ただし、ピクルファイルが空であることに驚いた場合、「wb」またはファイルを上書きする可能性のある他のモードでファイル名を開いたことが原因である可能性があります。

例えば:

filename = 'cd.pkl'
with open(filename, 'wb') as f:
    classification_dict = pickle.load(f)

これにより、ピクルされたファイルが上書きされます。以下を使用する前に誤ってこれを行った可能性があります。

...
open(filename, 'rb') as f:

前のコードブロックがcd.pklファイルを上書きしたため、EOFErrorが発生しました。

Jupyterまたはコンソール(Spyder)で作業する場合、通常、読み取り/書き込みコードの上にラッパーを記述し、その後ラッパーを呼び出します。これにより、一般的な読み取り/書き込みミスを回避し、travailsで同じファイルを複数回読み取る場合に少し時間を節約できます。

71
Abhay Nainan

ご覧のとおり、これは実際には自然なエラーです..

Unpicklerオブジェクトから読み取るための典型的な構造は、このようになります。

try:
    data = unpickler.load()
except EOFError:
    data = list()  # or whatever you want

EOFErrorは単に空のファイルを読み込んでいたため、単に発生しました。 ファイルの終わり ..

3
Amr Ayman
if path.exists(Score_file):
      try : 
         with open(Score_file , "rb") as prev_Scr:

            return Unpickler(prev_Scr).load()

    except EOFError : 

        return dict() 
1
jukoo

その例外をキャッチして、そこから必要なものを返すことができます。

open(target, 'a').close()
scores = {};
try:
    with open(target, "rb") as file:
        unpickler = pickle.Unpickler(file);
        scores = unpickler.load();
        if not isinstance(scores, dict):
            scores = {};
except EOFError:
    return {}
1
jramirez