it-swarm.com.de

Wie serialisiere ich ein Python Wörterbuch in einen String und dann zurück in ein Wörterbuch?

Wie serialisiere ich ein Python in eine Zeichenfolge und dann zurück zu einem Wörterbuch? Das Wörterbuch enthält Listen und andere Wörterbücher.

59
TIMEX

Es hängt davon ab, wofür Sie es verwenden möchten. Wenn Sie nur versuchen, es zu speichern, sollten Sie pickle verwenden (oder, wenn Sie CPython 2.x verwenden, cPickle , was 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 json verwenden:

>>> import json
>>> json.dumps({'foo': 'bar'})
'{"foo": "bar"}'
>>> json.loads(_)
{'foo': 'bar'}

json wird jedoch nur sehr begrenzt unterstützt, während pickle für beliebige Objekte verwendet werden kann (wenn dies nicht automatisch funktioniert, kann die Klasse __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
96
Chris Morgan

Verwenden Sie das Python-Modul json oder simplejson , wenn Sie nicht über python 2.6 oder höher verfügen.

11
Dan D.

Pickle ist großartig, aber ich denke, es lohnt sich, literal_eval Aus dem ast -Modul für eine noch leichtere Lösung zu erwähnen, wenn Sie nur einfache python= Typen serialisieren. Es ist im Grunde eine "sichere" Version der berüchtigten eval - Funktion, die nur die Auswertung von einfachen python - Typen erlaubt, im Gegensatz zu jedem gültigen python - Code.

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, also sehr menschenfreundlich sind. Vergleichen Sie sie mit dem, was Sie mit pickle.dumps Erhalten würden:

>>> 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 literal_ast Nicht unterstützt wird, zu etwas anderem übergehen müssen, wie Beizen.

10
Graphics Noob

Wenn Sie voll und ganz dem String vertrauen und sich nicht um Python-Injection-Attacken kümmern, dann 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, dann ast.literal_eval ist eine bessere Wette.

10
yoyo

Eine Sache, die json nicht kann, ist dict, das mit Ziffern indiziert ist. Das folgende Snippet

import 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 entpackte dict kann sofort verwendet werden.

4
Przemek D

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

1
georg

Auch wenn dies keine reine Serialisierung ist, ist JSON hier möglicherweise ein vernünftiger Ansatz. Damit werden verschachtelte Wörter, Listen und Daten verarbeitet, sofern es sich um "einfache" Daten handelt: Zeichenfolgen und grundlegende numerische Typen.

1
Tyler Eaves