web-dev-qa-db-fra.com

Pourquoi ai-je le message "Pickle - EOFError: Ran out of input" lors de la lecture d'un fichier vide?

J'obtiens une erreur intéressante en essayant d'utiliser Unpickler.load(), voici le code source:

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

Voici la traceback:

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

Le fichier que j'essaie de lire est vide ..__ Comment éviter cette erreur et obtenir une variable vide?

46
Magix

Je voudrais vérifier que le fichier n'est pas vide en premier:

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

De plus, open(target, 'a').close() ne fait rien dans votre code et vous n'avez pas besoin d'utiliser ;.

54
Padraic Cunningham

La plupart des réponses ici traitent de la gestion des exceptions EOFError, ce qui est très pratique si vous ne savez pas si l'objet picklé est vide ou non.

Cependant, si vous êtes surpris que le fichier de pickle est vide, c'est peut-être parce que vous avez ouvert le nom de fichier par le biais de 'wb' ou d'un autre mode qui aurait pu écraser le fichier.

par exemple:

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

Cela écrasera le fichier picklé. Vous avez peut-être fait cela par erreur avant d'utiliser:

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

Et puis, j'ai eu EOFError car le bloc de code précédent a écrasé le fichier cd.pkl. 

Lorsque je travaille dans Jupyter ou dans la console (Spyder), j'écris généralement un wrapper par-dessus le code de lecture/écriture et appelle le wrapper par la suite. Cela évite les erreurs courantes de lecture-écriture et permet de gagner un peu de temps si vous lisez le même fichier plusieurs fois au cours de vos tâches. 

39
Abhay Nainan

Comme vous le voyez, c'est en fait une erreur naturelle ..

Une construction typique pour la lecture d'un objet Unpickler serait comme ceci.

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

EOFError est simplement déclenché, car il lisait un fichier vide, cela signifiait simplement Fin de fichier ..

3
Amr Ayman

Vous pouvez attraper cette exception et retourner ce que vous voulez à partir de là. 

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
if path.exists(Score_file):
      try : 
         with open(Score_file , "rb") as prev_Scr:

            return Unpickler(prev_Scr).load()

    except EOFError : 

        return dict() 
0
jukoo