如何将Python字典序列化为字符串,然后返回字典?

问题描述 投票:54回答:8

如何将Python字典序列化为字符串,然后返回字典?字典里面会有列表和其他字典。

python string list serialization dictionary
8个回答
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

10
投票

如果你没有python 2.6或更高版本,请使用Python的json模块或simplejson


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是一个更好的选择。


8
投票

Pickle很棒,但我认为值得一提的是来自literal_eval模块的ast,如果你只是序列化基本的python类型,那么它的重量更轻一些。它基本上是臭名昭着的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
投票

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


1
投票

虽然不是严格的序列化,但json在这里可能是合理的方法。只要您的数据“简单”,它就会处理嵌套的dicts和列表以及数据:字符串和基本数字类型。


1
投票

pyyaml也应该在这里提到。它既是人类可读的,也可以序列化任何python对象。 pyyaml在这里托管: https://bitbucket.org/xi/pyyaml


-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时会出现一些错误。

© www.soinside.com 2019 - 2024. All rights reserved.