Wie kann ich Pickle verwenden, um ein Diktat zu speichern?

370

Ich habe die Informationen in den Python-Dokumenten durchgesehen , bin aber immer noch ein wenig verwirrt. Könnte jemand Beispielcode posten, der eine neue Datei schreibt und dann pickle verwendet, um ein Wörterbuch darin abzulegen?

Chachmu
quelle
5
Lesen Sie dies durch: teigmannmann.com/PyMOTW/pickle und kommen Sie zurück, wenn Sie eine bestimmte Frage benötigen
pyfunc
2
-1 Siehe vorherige Kommentare. Versuch es. Wenn es dann nicht funktioniert hat (es wird nicht immer funktionieren), kann eine gerichtete Frage formuliert werden (zusammen mit einer oder zwei Hypothesen, die getestet und "abgefragt" werden können, möglicherweise bevor die Frage an andere Personen gestellt wird). ZB gab es einen Syntaxfehler? Eine Ausnahme? Sind die Werte verstümmelt zurückgekommen?
1
Ich habe versucht, dies zu verwenden, um Informationen aus Pygame zu speichern. Ich habe die obigen Informationen verwendet und mein Code sieht folgendermaßen aus:
Chachmu
name = raw_input ('Name der Eingabedatei:') tf = open (Name + '. pkl', 'wb') pickle.dump (total, tf) tf.close ()
Chachmu
2
Sie sollten eine neue Frage zum Beizen von Oberflächenobjekten stellen
John La Rooy

Antworten:

727

Versuche dies:

import pickle

a = {'hello': 'world'}

with open('filename.pickle', 'wb') as handle:
    pickle.dump(a, handle, protocol=pickle.HIGHEST_PROTOCOL)

with open('filename.pickle', 'rb') as handle:
    b = pickle.load(handle)

print a == b
Mixer
quelle
4
@houbysoft: Warum hast du entfernt pickle.HIGHEST_PROTOCOL?
Blender
37
@Blender: irrelevant und unnötig kompliziert für diese Fragestufe - der durchschnittliche Benutzer wird mit den Standardeinstellungen gut zurechtkommen.
Houbysoft
28
@houbysoft: Richtig für Python 3-Benutzer, aber unter Python 2 ist die Verwendung des Standardprotokolls (0) nicht nur zeitlich und räumlich unglaublich ineffizient, sondern kann auch nicht viele Dinge handhaben, die Protokoll 2+ gut handhabt (z. B. neu) -Style-Klassen, die verwenden __slots__). Ich sage nicht, dass Sie immer verwenden sollten HIGHEST_PROTOCOL, aber sicherzustellen, dass Sie nicht Protokoll 0 oder 1 verwenden, ist eigentlich ziemlich wichtig.
ShadowRanger
11
Was macht pickle.HIGHEST_PROTOCOLeigentlich?
BallpointBen
7
@ BallpointBen: Es wählt die höchste Protokollversion, die Ihre Version von Python unterstützt: docs.python.org/3/library/pickle.html#data-stream-format
Blender
92
import pickle

your_data = {'foo': 'bar'}

# Store data (serialize)
with open('filename.pickle', 'wb') as handle:
    pickle.dump(your_data, handle, protocol=pickle.HIGHEST_PROTOCOL)

# Load data (deserialize)
with open('filename.pickle', 'rb') as handle:
    unserialized_data = pickle.load(handle)

print(your_data == unserialized_data)

Der Vorteil HIGHEST_PROTOCOList, dass Dateien kleiner werden. Dies macht das Lösen manchmal viel schneller.

Wichtiger Hinweis : Die maximale Dateigröße von pickle beträgt ca. 2 GB.

Alternativer Weg

import mpu
your_data = {'foo': 'bar'}
mpu.io.write('filename.pickle', data)
unserialized_data = mpu.io.read('filename.pickle')

Alternative Formate

Für Ihre Anwendung kann Folgendes wichtig sein:

  • Unterstützung durch andere Programmiersprachen
  • Lese- / Schreibleistung
  • Kompaktheit (Dateigröße)

Siehe auch: Vergleich der Datenserialisierungsformate

Wenn Sie eher nach einer Möglichkeit suchen, Konfigurationsdateien zu erstellen, lesen Sie möglicherweise meinen kurzen Artikel Konfigurationsdateien in Python

Martin Thoma
quelle
1
Ich denke, das 2-GB-Limit wurde mit Protokoll = 4 und höher entfernt.
ComputerScientist
28
# Save a dictionary into a pickle file.
import pickle

favorite_color = {"lion": "yellow", "kitty": "red"}  # create a dictionary
pickle.dump(favorite_color, open("save.p", "wb"))  # save it into a file named save.p

# -------------------------------------------------------------
# Load the dictionary back from the pickle file.
import pickle

favorite_color = pickle.load(open("save.p", "rb"))
# favorite_color is now {"lion": "yellow", "kitty": "red"}
user3465692
quelle
1
ist es notwendig, ein close () nach dem open () zu verwenden?
PlsWork
1
Ja im Allgemeinen. In CPython (dem Standard-Python, das Sie wahrscheinlich haben) wird die Datei jedoch automatisch geschlossen, wenn das Dateiobjekt abläuft (wenn nichts darauf verweist). In diesem Fall wird, da sich nach der Rückgabe durch open () nichts auf das Dateiobjekt bezieht, es geschlossen, sobald das Laden zurückkehrt. Dies wird nicht als bewährte Methode angesehen und führt zu Problemen auf anderen Systemen
Ankur S
14

Im Allgemeinen schlägt das Beizen von a dictfehl, es sei denn, Sie haben nur einfache Objekte wie Zeichenfolgen und Ganzzahlen.

Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from numpy import *
>>> type(globals())     
<type 'dict'>
>>> import pickle
>>> pik = pickle.dumps(globals())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle module objects
>>> 

Selbst ein wirklich einfacher dictwird oft scheitern. Es kommt nur auf den Inhalt an.

>>> d = {'x': lambda x:x}
>>> pik = pickle.dumps(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <function <lambda> at 0x102178668>: it's not found as __main__.<lambda>

Wenn Sie jedoch einen besseren Serializer wie dilloder verwenden cloudpickle, können die meisten Wörterbücher eingelegt werden:

>>> import dill
>>> pik = dill.dumps(d)

Oder wenn Sie Ihre dictin einer Datei speichern möchten ...

>>> with open('save.pik', 'w') as f:
...   dill.dump(globals(), f)
... 

Das letztere Beispiel ist identisch mit allen anderen hier veröffentlichten guten Antworten (die, abgesehen von der Vernachlässigung der Auswahlbarkeit der Inhalte, dictgut sind).

Mike McKerns
quelle
9
>>> import pickle
>>> with open("/tmp/picklefile", "wb") as f:
...     pickle.dump({}, f)
... 

Normalerweise ist es vorzuziehen, die cPickle-Implementierung zu verwenden

>>> import cPickle as pickle
>>> help(pickle.dump)
Help on built-in function dump in module cPickle:

dump(...)
    dump(obj, file, protocol=0) -- Write an object in pickle format to the given file.

    See the Pickler docstring for the meaning of optional argument proto.
John La Rooy
quelle
6

Wenn Sie das Diktat nur in einer einzigen Datei speichern möchten, verwenden Sie es picklewie folgt

import pickle

a = {'hello': 'world'}

with open('filename.pickle', 'wb') as handle:
    pickle.dump(a, handle)

with open('filename.pickle', 'rb') as handle:
    b = pickle.load(handle)

Wenn Sie mehrere Wörterbücher in mehreren Dateien zum Zwischenspeichern und Speichern komplexerer Daten speichern und wiederherstellen möchten, verwenden Sie anycache . Es erledigt alle anderen Dinge, die Sie brauchenpickle

from anycache import anycache

@anycache(cachedir='path/to/files')
def myfunc(hello):
    return {'hello', hello}

Anycache speichert die unterschiedlichen myfuncErgebnisse abhängig von den Argumenten in verschiedenen Dateien cachedirund lädt sie neu.

Weitere Einzelheiten finden Sie in der Dokumentation .

c0fec0de
quelle
6

Einfache Möglichkeit, Python-Daten (z. B. ein Wörterbuch) in eine Pickle-Datei zu kopieren.

import pickle

your_dictionary = {}

pickle.dump(your_dictionary, open('pickle_file_name.p', 'wb'))
Prashanth Muthurajaiah
quelle
3
import pickle

dictobj = {'Jack' : 123, 'John' : 456}

filename = "/foldername/filestore"

fileobj = open(filename, 'wb')

pickle.dump(dictobj, fileobj)

fileobj.close()
Rahul Nair
quelle
-8

Ich fand das Beizen verwirrend (möglicherweise weil ich dick bin). Ich fand jedoch, dass dies funktioniert:

myDictionaryString=str(myDictionary)

Was Sie dann in eine Textdatei schreiben können. Ich habe den Versuch, pickle zu verwenden, aufgegeben, da ich Fehler bekam, die mich aufforderten, Ganzzahlen in eine .dat-Datei zu schreiben. Ich entschuldige mich dafür, dass ich keine Gurke benutze.

Pedro Rhian
quelle
1
-1: Sollte es so speichern, wie es ist (dh ein Python-Objekt), damit wir es später lesen können, ohne stundenlang darauf warten zu müssen, es erneut auszuführen. Mit Pickle können wir ein Python-Objekt speichern, um es später zu lesen.
Catbuilts
Dies ist eine alte Antwort, die in der Warteschlange für Posts mit geringer Qualität zurückkommt. Es ist keine schlechte Lösung, da sie wahrscheinlich für sehr einfache Wörterbücher funktioniert, aber es ist sehr vernünftig, eine dictweitere Tiefe von Objekten zu enthalten (die möglicherweise nur von gedruckt werden) Name) und / oder Objekte ohne oder mit vollständiger Zeichenfolgendarstellung.
7.
1
Unabhängig vom technischen Wert der Antwort ist dieser Beitrag kein VLQ. Wenn jemand der Meinung ist, dass diese Antwort ungenau ist, sollte er abstimmen und / oder kommentieren, um zu erklären, warum, und sie nicht als VLQ markieren.
EJoshuaS - Monica