如何将Python字典序列化为字符串,然后返回字典?字典里面会有列表和其他字典。
答案 0 :(得分:92)
这取决于你想要用它做什么。如果你只是想保存它,你应该使用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
答案 1 :(得分:10)
使用Python的json模块,如果没有python 2.6或更高版本,则使用simplejson。
答案 2 :(得分:9)
如果你完全信任字符串而不关心python injection attacks那么这是一个非常简单的解决方案:
d = { 'method' : "eval", 'safe' : False, 'guarantees' : None }
s = str(d)
d2 = eval(s)
for k in d2:
print k+"="+d2[k]
如果你更注重安全,那么ast.literal_eval
是更好的选择。
答案 3 :(得分:8)
Pickle非常棒,但我认为如果您只是序列化基本的python类型,那么literal_eval
模块中的ast
值得提及更轻量级的解决方案。它基本上是一个安全的&#34;臭名昭着的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
不支持的类型,您就必须转换为其他类似酸洗的内容。
答案 4 :(得分:4)
json
无法做到的一件事是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
。
答案 5 :(得分:1)
虽然不是严格的序列化,但json在这里可能是合理的方法。只要您的数据“简单”,它就会处理嵌套的dicts和列表以及数据:字符串和基本数字类型。
答案 6 :(得分:1)
pyyaml 也应该在这里提到。它既是人类可读的,也可以序列化任何python对象
pyyaml在这里举办:
https://bitbucket.org/xi/pyyaml
答案 7 :(得分:-2)
如果您只是尝试序列化,那么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时会出现一些错误。