web-dev-qa-db-fra.com

pickle - mettre plus d'un objet dans un fichier?

J'ai une méthode qui vide un certain nombre d'objets marinés (tuples, en fait) dans un fichier.

Je ne veux pas les mettre dans une liste, je veux vraiment les vider plusieurs fois dans le même fichier. Mon problème est, comment puis-je recharger les objets? Le premier et le deuxième objet ne font qu'une ligne, donc cela fonctionne avec les lignes de lecture. Mais tous les autres sont plus longs. naturellement, si j'essaye

myob = cpickle.load(g1.readlines()[2])

où g1 est le fichier, j'obtiens une erreur EOF car mon objet mariné est plus long qu'une ligne. Existe-t-il un moyen d'obtenir uniquement mon objet mariné?

24
newnewbie

Si vous passez le descripteur de fichier directement dans le cornichon, vous pouvez obtenir le résultat souhaité.

import pickle

# write a file
f = open("example", "w")
pickle.dump(["hello", "world"], f)
pickle.dump([2, 3], f)
f.close()

f = open("example", "r")
value1 = pickle.load(f)
value2 = pickle.load(f)
f.close()

pickle.dump s'ajoutera à la fin du fichier, vous pouvez donc l'appeler plusieurs fois pour écrire plusieurs valeurs.

pickle.load ne lira que suffisamment du fichier pour obtenir la première valeur, laissant le descripteur de fichier ouvert et pointé au début de l'objet suivant dans le fichier. Le deuxième appel lira ensuite le deuxième objet et laissera le pointeur de fichier à la fin du fichier. Un troisième appel échouera avec un EOFError comme vous vous en doutez.

Bien que j'aie utilisé du vieux pickle dans mon exemple, cette technique fonctionne de la même façon avec cPickle.

70
Martin Atkins

Je pense que la meilleure façon est de regrouper vos données dans un seul objet avant de les stocker et de les décompresser après leur chargement. Voici un exemple utilisant un Tuple comme conteneur (you can use dict also):

a = [1,2]
b = [3,4]

with open("tmp.pickle", "wb") as f:
    pickle.dump((a,b), f)

with open("tmp.pickle", "rb") as f:
    a,b = pickle.load(f) 
17
Samuel

N'essayez pas de les relire en tant que lignes du fichier, justepickle.load() le nombre d'objets que vous voulez. Voir ma réponse à la question Comment enregistrer un objet en Python pour un exemple de faire cela.

1
martineau