Wie serialisiere ich ein Python-Wörterbuch in eine Zeichenfolge und dann zurück in ein Wörterbuch? Das Wörterbuch enthält Listen und andere Wörterbücher.
73
Wie serialisiere ich ein Python-Wörterbuch in eine Zeichenfolge und dann zurück in ein Wörterbuch? Das Wörterbuch enthält Listen und andere Wörterbücher.
pickle
?Antworten:
Es hängt davon ab, wofür Sie es verwenden möchten. Wenn Sie nur versuchen, es zu speichern, sollten Sie es verwenden
pickle
(oder, wenn Sie CPython 2.x verwendencPickle
, das schneller ist).>>> import pickle >>> pickle.dumps({'foo': 'bar'}) b'\x80\x03}q\x00X\x03\x00\x00\x00fooq\x01X\x03\x00\x00\x00barq\x02s.' >>> pickle.loads(_) {'foo': 'bar'}
Wenn Sie möchten, dass es lesbar ist, können Sie Folgendes verwenden
json
:>>> import json >>> json.dumps({'foo': 'bar'}) '{"foo": "bar"}' >>> json.loads(_) {'foo': 'bar'}
json
ist jedoch sehr begrenzt in der Unterstützung, währendpickle
es für beliebige Objekte verwendet werden kann (wenn es nicht automatisch funktioniert, kann die Klasse definieren__getstate__
, um genau anzugeben, wie es eingelegt werden soll).>>> pickle.dumps(object()) b'\x80\x03cbuiltins\nobject\nq\x00)\x81q\x01.' >>> json.dumps(object()) Traceback (most recent call last): ... TypeError: <object object at 0x7fa0348230c0> is not JSON serializable
quelle
In Python 3.0... Users should always import the standard version, which attempts to import the accelerated version and falls back to the pure Python version.
Verwenden Sie das json- Modul von Python oder simplejson, wenn Sie nicht über Python 2.6 oder höher verfügen.
quelle
json.dumps(mydict)
undjson.loads(mystring)
json.dumps()
kümmern sich um einige Arten (False
,True
, undNone
) , weil sie mit nicht kompatibel sindjson
Wenn Sie der Zeichenfolge voll vertrauen und sich nicht für Python-Injektionsangriffe interessieren, ist dies eine sehr einfache Lösung:
d = { 'method' : "eval", 'safe' : False, 'guarantees' : None } s = str(d) d2 = eval(s) for k in d2: print k+"="+d2[k]
Wenn Sie sicherheitsbewusster sind,
ast.literal_eval
ist dies eine bessere Wahl.quelle
ast.literal_eval
standardmäßig verwenden.eval
hat keine Mehrwert und ein großes Sicherheitsproblem.eval
weg können. Ich bin jedes Mal nur angewidert, jemand fördert diese Kultur der Schlamperei. Verwenden Sie einfachjson.dumps
undjson.loads
(oder eine andere Nichtlösungeval
), es gibt keinen wirklichen Grund, dies nicht zuPickle ist großartig, aber ich denke, es ist erwähnenswert,
literal_eval
dasast
Modul für eine noch leichtere Lösung zu erwähnen, wenn Sie nur grundlegende Python-Typen serialisieren. Es ist im Grunde eine "sichere" Version der berüchtigteneval
Funktion, die nur die Bewertung grundlegender Python-Typen im Gegensatz zu einem gültigen Python-Code ermöglicht.Beispiel:
>>> d = {} >>> d[0] = range(10) >>> d['1'] = {} >>> d['1'][0] = range(10) >>> d['1'][1] = 'hello' >>> data_string = str(d) >>> print data_string {0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], '1': {0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 1: 'hello'}} >>> from ast import literal_eval >>> d == literal_eval(data_string) True
Ein Vorteil ist, dass die serialisierten Daten nur Python-Code sind und daher sehr menschenfreundlich sind. Vergleichen Sie es mit dem, was Sie bekommen würden
pickle.dumps
:>>> import pickle >>> print pickle.dumps(d) (dp0 I0 (lp1 I0 aI1 aI2 aI3 aI4 aI5 aI6 aI7 aI8 aI9 asS'1' p2 (dp3 I0 (lp4 I0 aI1 aI2 aI3 aI4 aI5 aI6 aI7 aI8 aI9 asI1 S'hello' p5 ss.
Der Nachteil ist, dass Sie, sobald die Daten einen Typ enthalten, der von nicht unterstützt wird
literal_ast
, zu etwas anderem wie Beizen übergehen müssen.quelle
Eine Sache,
json
die nicht getan werden kann, ist diedict
Indizierung mit Ziffern. Das folgende Snippetimport json dictionary = dict({0:0, 1:5, 2:10}) serialized = json.dumps(dictionary) unpacked = json.loads(serialized) print(unpacked[0])
wird werfen
KeyError: 0
Weil Schlüssel in Zeichenfolgen konvertiert werden.
cPickle
behält den numerischen Typ bei und das entpacktedict
kann sofort verwendet werden.quelle
Obwohl dies keine strikte Serialisierung ist, kann json hier ein vernünftiger Ansatz sein. Damit werden verschachtelte Dikte und Listen sowie Daten behandelt, solange Ihre Daten "einfach" sind: Zeichenfolgen und grundlegende numerische Typen.
quelle
Pyyaml sollte auch hier erwähnt werden. Es ist sowohl für Menschen lesbar als auch kann jedes Python-Objekt serialisieren.
pyyaml wird hier gehostet:
https://bitbucket.org/xi/pyyaml
quelle
Wenn Sie nur serialisieren möchten, ist pprint möglicherweise auch eine gute Option. Es erfordert die Serialisierung des Objekts und einen Dateistream.
Hier ist ein Code:
from pprint import pprint my_dict = {1:'a',2:'b'} with open('test_results.txt','wb') as f: pprint(my_dict,f)
Ich bin mir nicht sicher, ob wir leicht deserialisieren können. Ich habe json früher zum Serialisieren und Deserialisieren verwendet, was in den meisten Fällen korrekt funktioniert.
f.write(json.dumps(my_dict, sort_keys = True, indent = 2, ensure_ascii=True))
In einem bestimmten Fall gab es jedoch einige Fehler beim Schreiben von Nicht-Unicode-Daten in json.
quelle