如何将Python字典序列化为字符串,然后再返回字典?该词典中将包含列表和其他词典。
Answers:
这取决于您要使用它的目的。如果只是尝试保存它,则应使用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模块,如果您没有python 2.6或更高版本,请使用simplejson。
json.dumps(mydict)
和json.loads(mystring)
json.dumps()
,请注意某些类型(False
,True
和None
),因为它们与json
如果您完全信任该字符串并且不关心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
是更好的选择。
ast.literal_eval
默认使用。eval
具有零附加值和很大的安全问题。
eval
走开。每次我都感到很恶心,有人提倡这种卑鄙的文化。只需使用json.dumps
和json.loads
(或任何其他非eval
解决方案),没有真正的理由不这样做
Pickle很棒,但是如果您只序列化基本的python类型,那么我认为值得literal_eval
在ast
模块中提供更轻量的解决方案。这基本上是臭名昭著的“安全”版本eval
函数它仅允许评估基本的python类型,而不是任何有效的python代码。
例:
>>> 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
好处之一是序列化的数据只是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
您不支持的类型,您就必须过渡到其他类型,例如酸洗。
如果您只尝试序列化,那么pprint也是一个不错的选择。它要求序列化对象和文件流。
这是一些代码:
from pprint import pprint
my_dict = {1:'a',2:'b'}
with open('test_results.txt','wb') as f:
pprint(my_dict,f)
我不确定是否可以轻松地反序列化。我之前使用json序列化和反序列化,在大多数情况下都可以正常工作。
f.write(json.dumps(my_dict, sort_keys = True, indent = 2, ensure_ascii=True))
但是,在一种特定情况下,将非Unicode数据写入json会出现一些错误。
pickle
吗?