Ich versuche Objekte mit pickle
Modul zu speichern und zu laden .
Zuerst erkläre ich meine Objekte:
>>> class Fruits:pass
...
>>> banana = Fruits()
>>> banana.color = 'yellow'
>>> banana.value = 30
Danach öffne ich eine Datei mit dem Namen 'Fruits.obj' (zuvor habe ich eine neue TXT-Datei erstellt und 'Fruits.obj' umbenannt):
>>> import pickle
>>> filehandler = open(b"Fruits.obj","wb")
>>> pickle.dump(banana,filehandler)
Danach schließe ich meine Sitzung und beginne eine neue und setze die nächste (versuche auf das Objekt zuzugreifen, das gespeichert werden soll):
file = open("Fruits.obj",'r')
object_file = pickle.load(file)
Aber ich habe diese Nachricht:
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
Ich weiß nicht, was ich tun soll, weil ich diese Nachricht nicht verstehe. Weiß jemand, wie ich mein Objekt 'Banane' laden kann? Danke dir!
EDIT: Wie einige von Ihnen vorgeschlagen haben, habe ich gesagt:
>>> import pickle
>>> file = open("Fruits.obj",'rb')
Es gab kein Problem, aber das nächste, das ich sagte, war:
>>> object_file = pickle.load(file)
Und ich habe Fehler:
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
Antworten:
Wie für Ihr zweites Problem:
Nachdem Sie den Inhalt der Datei gelesen haben, befindet sich der Dateizeiger am Ende der Datei. Es sind keine weiteren Daten zu lesen. Sie müssen die Datei zurückspulen, damit sie wieder von Anfang an gelesen wird:
Normalerweise möchten Sie jedoch einen Kontextmanager verwenden, um die Datei zu öffnen und Daten daraus zu lesen. Auf diese Weise wird die Datei nach Abschluss der Ausführung des Blocks automatisch geschlossen. Dies hilft Ihnen auch dabei, Ihre Dateivorgänge in sinnvolle Abschnitte zu organisieren.
Schließlich ist cPickle eine schnellere Implementierung des Pickle-Moduls in C. Also:
quelle
{"a": 1, "b": 2}
ein Wörterbuch mit den Schlüsseln"a"
und"b"
darin. Dies wird in der Online-Dokumentation als Wörterbuchanzeigeausdruck bezeichnet . Dies ist nur eine von mehreren Möglichkeiten, wie ein Objekt vom Typdict
, bei dem es sich um einen von mehreren in Python integrierten Standarddatentypen handelt, erstellt werden kann.pickle
, dascpickle
automatisch importiert wird, wenn es kann. docs.python.org/3.1/whatsnew/3.0.html#library-changesFolgendes funktioniert für mich:
quelle
class Fruits
definiert haben, damitpickle.load()
das Objekt aus den Daten wiederhergestellt werden kann, die in der Binärdatei gespeichert wurden. Die beste Vorgehensweise für diese Art von Dingen besteht darin, dieclass Fruits
Definition in einer separaten .py-Datei abzulegen (wodurch sie zu einem benutzerdefinierten Modul wird) und dannimport
das Modul oder die Elemente daraus, wann immer dies erforderlich ist (dh beide Sitzungen). Wenn Sie es beispielsweise in eine Datei mit dem NamenMyDataDefs.py
einfügen, können Sie schreibenfrom MyDataDefs import Fruits
. Lassen Sie mich wissen, wenn dies unklar ist, und ich werde meine Antwort entsprechend aktualisieren.my_data_defs.py
using enthalten seinfrom my_data_defs import Fruits
.Sie vergessen, es auch als binär zu lesen.
In Ihrem Schreibteil haben Sie:
Im gelesenen Teil haben Sie:
Ersetzen Sie es also durch:
Und es wird funktionieren :)
Der zweite Fehler ist höchstwahrscheinlich darauf zurückzuführen, dass die Datei nicht ordnungsgemäß geschlossen / synchronisiert wurde.
Versuchen Sie diesen Code, um zu schreiben:
Und dies (unverändert) zu lesen:
Eine sauberere Version würde die
with
Anweisung verwenden.Zum Schreiben:
Zum Lesen:
quelle
In diesem Fall immer im Binärmodus geöffnet
quelle
Sie haben die Datei nicht im Binärmodus geöffnet.
Sollte arbeiten.
Bei Ihrem zweiten Fehler ist die Datei höchstwahrscheinlich leer, was bedeutet, dass Sie sie versehentlich geleert oder den falschen Dateinamen oder etwas anderes verwendet haben.
(Dies setzt voraus, dass Sie Ihre Sitzung wirklich geschlossen haben. Wenn nicht, liegt dies daran, dass Sie die Datei zwischen Schreiben und Lesen nicht geschlossen haben.)
Ich habe Ihren Code getestet und er funktioniert.
quelle
Es scheint, dass Sie Ihre Klasseninstanzen über Sitzungen hinweg speichern möchten, und die Verwendung
pickle
ist eine anständige Möglichkeit, dies zu tun. Es gibt jedoch ein Paket mit dem Namenklepto
, das das Speichern von Objekten in einer Wörterbuchschnittstelle abstrahiert. Sie können also Objekte auswählen und in einer Datei speichern (siehe Abbildung unten) oder Objekte auswählen und in einer Datenbank speichern oder stattdessen Verwenden Sie Pickle Use Json oder viele andere Optionen. Das Schöne daranklepto
ist, dass durch die Abstraktion zu einer gemeinsamen Benutzeroberfläche die Vereinfachung vereinfacht wird, sodass Sie sich nicht an die Details auf niedriger Ebene erinnern müssen, wie Sie durch Beizen in eine Datei oder auf andere Weise speichern können.Beachten Sie, dass es für dynamisch hinzugefügte Klassenattribute funktioniert, was Pickle nicht kann ...
Dann starten wir neu ...
Klepto
funktioniert auf python2 und python3.Den Code erhalten Sie hier: https://github.com/uqfoundation
quelle
Sie können anycache verwenden , um die Arbeit für Sie zu erledigen. Angenommen, Sie haben eine Funktion,
myfunc
die die Instanz erstellt:Anycache ruft
myfunc
beim ersten Mal auf und nimmt das Ergebnis in eine Datei aufcachedir
indem ein eindeutiger Bezeichner (abhängig vom Funktionsnamen und den Argumenten) als Dateiname verwendet wird. Bei jedem aufeinanderfolgenden Lauf wird das eingelegte Objekt geladen.Wenn die
cachedir
zwischen Python-Läufen erhalten bleibt, wird das eingelegte Objekt aus dem vorherigen Python-Lauf übernommen.Die Funktionsargumente werden ebenfalls berücksichtigt. Eine überarbeitete Implementierung funktioniert ebenfalls:
quelle