Почему я получаю "Pickle - EOFError: Ran из ввода", читающий пустой файл?

Я получаю интересную ошибку при попытке использовать 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

Файл, который я пытаюсь прочитать, пуст. Как я могу избежать получения этой ошибки и вместо этого получить пустую переменную?

Ответ 1

Я бы проверял, что файл сначала не пуст:

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() ничего не делает в вашем коде, и вам не нужно использовать ;.

Ответ 2

Большинство ответов здесь касались того, как обрабатывать исключения EOFError, что очень удобно, если вы не уверены, пуст ли засоленный объект или нет.

Однако, если вы удивлены, что файл pickle пуст, это может быть связано с тем, что вы открыли имя файла с помощью 'wb' или другого режима, который мог перезаписать файл.

например:

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

Это перезапишет маринованный файл. Возможно, вы сделали это по ошибке перед использованием:

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

А затем получил EOFError, потому что предыдущий блок кода переписал файл cd.pkl.

При работе в Jupyter или в консоли (Spyder) я обычно пишу оболочку поверх кода чтения/записи и впоследствии вызываю оболочку. Это позволяет избежать распространенных ошибок чтения и записи и сэкономит немного времени, если вы будете читать один и тот же файл несколько раз в трудностях.

Ответ 3

Как вы видите, это на самом деле естественная ошибка.

Типичная конструкция для чтения из объекта Unpickler будет выглядеть следующим образом.

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

EOFError просто поднят, потому что он читает пустой файл, это просто означает Конец файла..

Ответ 4

Вы можете поймать это исключение и вернуть все, что захотите.

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

Ответ 5

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

            return Unpickler(prev_Scr).load()

    except EOFError : 

        return dict() 

Ответ 6

Весьма вероятно, что маринованный файл пуст.

Удивительно легко перезаписать файл pickle, если вы копируете и вставляете код.

Например, следующий файл пишет файл рассола:

pickle.dump(df,open('df.p','wb'))

И если вы скопировали этот код, чтобы снова открыть его, но забыли изменить 'wb' на 'rb', тогда вы перезапишите файл:

df=pickle.load(open('df.p','rb'))

Правильный синтаксис:

df=pickle.load(open('df.p','wb'))