Python辞書を文字列にシリアル化してから辞書に戻すにはどうすればよいですか?辞書にはリストや他の辞書が含まれます。
それはあなたがそれを使用したいものに依存します。保存しようとしている場合は、 pickle
を使用する必要があります(または、CPython 2.xを使用している場合は、 cPickle
、これは高速です)。
>>> 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'}
読みやすくしたい場合は、 json
を使用できます。
>>> import json
>>> json.dumps({'foo': 'bar'})
'{"foo": "bar"}'
>>> json.loads(_)
{'foo': 'bar'}
ただし、json
はサポート対象が非常に制限されていますが、pickle
は任意のオブジェクトに使用できます(自動的に機能しない場合、クラスは__getstate__
どのようにピクルスにするかを正確に指定します)。
>>> 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
Pythonの json モジュールを使用するか、=がない場合は simplejson を使用しますpython 2.6以降。
Pickleは素晴らしいですが、基本的なpython型のみをシリアル化する場合、さらに軽量なソリューションのためにast
モジュールのliteral_eval
に言及する価値があると思います。基本的には有効なpythonコードに対して、基本的なpythonタイプの評価のみを許可する悪名高いeval
関数の「安全な」バージョン。
例:
>>> 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
利点の1つは、シリアル化されたデータがpythonコードであるため、非常に人間に優しいことです。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.
欠点は、データにliteral_ast
でサポートされていない型が含まれるとすぐに、ピクルスなどの別のものに移行する必要があることです。
If文字列を完全に信頼し、 pythonインジェクション攻撃 を気にしない場合、これは非常に簡単なソリューションです:
d = { 'method' : "eval", 'safe' : False, 'guarantees' : None }
s = str(d)
d2 = eval(s)
for k in d2:
print k+"="+d2[k]
あなたがより安全を意識しているなら、 ast.literal_eval
の方が良い方法です。
json
ができないことの1つは、数字でインデックス付けされたdict
です。次のスニペット
import json
dictionary = dict({0:0, 1:5, 2:10})
serialized = json.dumps(dictionary)
unpacked = json.loads(serialized)
print unpacked[0]
投げます
KeyError: 0
キーが文字列に変換されるため。 cPickle
は数値型を保持し、解凍されたdict
はすぐに使用できます。
pyyamlもここに記載する必要があります。人間が読める形式であり、任意のpythonオブジェクトをシリアル化できます。
pyyamlはここでホストされます:
https://bitbucket.org/xi/pyyaml
厳密にシリアライズされていませんが、ここではjsonが妥当なアプローチかもしれません。データが「単純」である限り、ネストされた辞書とリスト、およびデータを処理します:文字列と基本的な数値型。