web-dev-qa-db-fra.com

Comment lire le fichier pickle?

J'ai créé des données et les ai stockées plusieurs fois comme ceci:

with open('filename', 'a') as f:
        pickle.dump(data, f)

A chaque fois que la taille du fichier a augmenté, mais quand j'ouvre le fichier

with open('filename', 'rb') as f:
    x = pickle.load(f)

Je ne peux voir que les données de la dernière fois. Comment puis-je lire correctement le fichier?

39
Kenenbek Arzymatov

Pickle sérialise un seul objet à la fois et lit un seul objet. Les données picklées sont enregistrées en séquence dans le fichier.

Si vous faites simplement pickle.load, vous devriez lire le premier objet sérialisé dans le fichier (et non le dernier tel que vous l'avez écrit).

Après avoir désérialisé le premier objet, le pointeur de fichier est au début de l'objet suivant. Si vous appelez simplement de nouveau pickle.load, il lira cet objet suivant. Faites-le jusqu'à la fin du fichier.

objects = []
with (open("myfile", "rb")) as openfile:
    while True:
        try:
            objects.append(pickle.load(openfile))
        except EOFError:
            break
55
jsbueno

Voici un exemple de la manière dont vous pourriez écrire et lire un fichier pickle. Notez que si vous continuez à ajouter des données de pickle au fichier, vous devrez continuer à lire le fichier jusqu'à ce que vous trouviez ce que vous souhaitiez ou qu'une exception soit générée en atteignant la fin du fichier. C'est ce que fait la dernière fonction.

import os
import pickle


PICKLE_FILE = 'pickle.dat'


def main():
    # append data to the pickle file
    add_to_pickle(PICKLE_FILE, 123)
    add_to_pickle(PICKLE_FILE, 'Hello')
    add_to_pickle(PICKLE_FILE, None)
    add_to_pickle(PICKLE_FILE, b'World')
    add_to_pickle(PICKLE_FILE, 456.789)
    # load & show all stored objects
    for item in read_from_pickle(PICKLE_FILE):
        print(repr(item))
    os.remove(PICKLE_FILE)


def add_to_pickle(path, item):
    with open(path, 'ab') as file:
        pickle.dump(item, file, pickle.HIGHEST_PROTOCOL)


def read_from_pickle(path):
    with open(path, 'rb') as file:
        try:
            while True:
                yield pickle.load(file)
        except EOFError:
            pass


if __== '__main__':
    main()
6
Noctis Skytower