J'essaye de sauvegarder et de charger des objets en utilisant le pickle
module.
Je déclare d'abord mes objets:
>>> class Fruits:pass
...
>>> banana = Fruits()
>>> banana.color = 'yellow'
>>> banana.value = 30
Après cela, j'ouvre un fichier appelé 'Fruits.obj' (auparavant, j'ai créé un nouveau fichier .txt et j'ai renommé 'Fruits.obj'):
>>> import pickle
>>> filehandler = open(b"Fruits.obj","wb")
>>> pickle.dump(banana,filehandler)
Après cela, je ferme ma session et j'en ai commencé une nouvelle et j'ai mis la suivante (en essayant d'accéder à l'objet qu'elle supposait être sauvé):
file = open("Fruits.obj",'r')
object_file = pickle.load(file)
Mais j'ai ce message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
ValueError: read() from the underlying stream did notreturn bytes
Je ne sais pas quoi faire car je ne comprends pas ce message. Quelqu'un sait-il comment je peux charger mon objet «banane»? Je vous remercie!
EDIT: Comme certains d'entre vous l'ont suggéré, j'ai mis:
>>> import pickle
>>> file = open("Fruits.obj",'rb')
Il n'y a pas eu de problème, mais le prochain que j'ai mis était:
>>> object_file = pickle.load(file)
Et j'ai une erreur:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
EOFError
Réponses:
Quant à votre deuxième problème:
Après avoir lu le contenu du fichier, le pointeur de fichier sera à la fin du fichier - il n'y aura plus de données à lire. Vous devez rembobiner le fichier pour qu'il soit à nouveau lu depuis le début:
Cependant, ce que vous voulez généralement faire, c'est utiliser un gestionnaire de contexte pour ouvrir le fichier et en lire les données. De cette façon, le fichier sera automatiquement fermé une fois l'exécution du bloc terminée, ce qui vous aidera également à organiser vos opérations sur les fichiers en morceaux significatifs.
Enfin, cPickle est une implémentation plus rapide du module pickle en C. Donc:
la source
{"a": 1, "b": 2}
crée un dictionnaire avec les clés"a"
et"b"
dedans. C'est ce qu'on appelle une expression d'affichage de dictionnaire dans la documentation en ligne. C'est juste l'une des différentes manières dont un objet de typedict
, qui est l'un des nombreux types de données intégrés standard disponibles en Python, peut être construit.pickle
qui importeracpickle
automatiquement si cela peut. docs.python.org/3.1/whatsnew/3.0.html#library-changesCe qui suit fonctionne pour moi:
la source
class Fruits
défini afin depickle.load()
pouvoir reconstituer l'objet à partir des données qui ont été enregistrées dans le fichier binaire. La meilleure pratique pour ce genre de chose est de mettre laclass Fruits
définition dans un fichier .py séparé (ce qui en fait un module personnalisé), puisimport
ce module ou ses éléments chaque fois que nécessaire (c'est-à-dire les deux sessions). Par exemple, si vous le mettez dans un fichier nommé,MyDataDefs.py
vous pouvez écrirefrom MyDataDefs import Fruits
. Faites-moi savoir si cela n'est pas clair et je mettrai à jour ma réponse en conséquence.my_data_defs.py
usingfrom my_data_defs import Fruits
.Vous oubliez de le lire aussi en binaire.
Dans votre partie d'écriture, vous avez:
Dans la partie lue, vous avez:
Alors remplacez-le par:
Et cela fonctionnera :)
Quant à votre deuxième erreur, elle est probablement due à une mauvaise fermeture / synchronisation du fichier.
Essayez ce morceau de code pour écrire:
Et ceci (inchangé) à lire:
Une version plus soignée utiliserait la
with
déclaration.Pour écrire:
À lire:
la source
Toujours ouvert en mode binaire, dans ce cas
la source
Vous n'avez pas ouvert le fichier en mode binaire.
Devrait marcher.
Pour votre deuxième erreur, le fichier est très probablement vide, ce qui signifie que vous l'avez vidé par inadvertance ou que vous avez utilisé le mauvais nom de fichier ou quelque chose.
(Cela suppose que vous avez vraiment fermé votre session. Sinon, c'est parce que vous n'avez pas fermé le fichier entre l'écriture et la lecture).
J'ai testé votre code et cela fonctionne.
la source
Il semble que vous souhaitiez enregistrer vos instances de classe entre les sessions, et l'utilisation
pickle
est un moyen décent de le faire. Cependant, il existe un package appeléklepto
qui fait abstraction de l'enregistrement des objets dans une interface de dictionnaire, vous pouvez donc choisir de sélectionner les objets et de les enregistrer dans un fichier (comme indiqué ci-dessous), ou de sélectionner les objets et de les enregistrer dans une base de données, ou au lieu de use pickle use json, ou bien d'autres options. La bonne chose à propos deklepto
c'est que l'abstraction vers une interface commune facilite les choses afin que vous n'ayez pas à vous souvenir des détails de bas niveau sur la façon de sauvegarder via le décapage dans un fichier, ou autrement.Notez que cela fonctionne pour les attributs de classe ajoutés dynamiquement, ce que Pickle ne peut pas faire ...
Puis on recommence…
Klepto
fonctionne sur python2 et python3.Obtenez le code ici: https://github.com/uqfoundation
la source
Vous pouvez utiliser anycache pour faire le travail à votre place. En supposant que vous ayez une fonction
myfunc
qui crée l'instance:Anycache appelle
myfunc
à la première fois et sélectionne le résultat dans un fichier encachedir
utilisant un identifiant unique (en fonction du nom de la fonction et des arguments) comme nom de fichier. Lors de toute exécution consécutive, l'objet décapé est chargé.Si le
cachedir
est conservé entre les exécutions de python, l'objet pickled est extrait de l'exécution de python précédente.Les arguments de la fonction sont également pris en compte. Une implémentation refactorisée fonctionne de la même manière:
la source