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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4342176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 15:19:32  来源:igfitidea点击:

How do I serialize a Python dictionary into a string, and then back to a dictionary?

pythonstringlistserializationdictionary

提问by TIMEX

How do I serialize a Python dictionary into a string, and then back to a dictionary? The dictionary will have lists and other dictionaries inside it.

如何将 Python 字典序列化为字符串,然后再返回到字典?该词典将包含列表和其他词典。

采纳答案by Chris Morgan

It depends on what you're wanting to use it for. If you're just trying to save it, you should use pickle(or, if you're using CPython 2.x, cPickle, which is faster).

这取决于你想用它做什么。如果您只是想保存它,则应该使用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'}

If you want it to be readable, you could use json:

如果你想让它可读,你可以使用json

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

jsonis, however, very limited in what it will support, while picklecan be used for arbitrary objects (if it doesn't work automatically, the class can define __getstate__to specify precisely how it should be pickled).

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

回答by Dan D.

Use Python's jsonmodule, or simplejsonif you don't have python 2.6 or higher.

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

回答by Tyler Eaves

While not strictly serialization, json may be reasonable approach here. That will handled nested dicts and lists, and data as long as your data is "simple": strings, and basic numeric types.

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

回答by georg

pyyamlshould also be mentioned here. It is both human readable and can serialize any python object.
pyyaml is hosted here:
https://bitbucket.org/xi/pyyaml

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

回答by smartexpert

If you are trying to only serialize then pprint may also be a good option. It requires the object to be serialized and a file stream.

如果您只想序列化,那么 pprint 也可能是一个不错的选择。它需要序列化对象和文件流。

Here's some code:

这是一些代码:

from pprint import pprint
my_dict = {1:'a',2:'b'}
with open('test_results.txt','wb') as f:
    pprint(my_dict,f)

I am not sure if we can deserialize easily. I was using json to serialize and deserialze earlier which works correctly in most cases.

我不确定我们是否可以轻松反序列化。我之前使用 json 进行序列化和反序列化,这在大多数情况下都能正常工作。

f.write(json.dumps(my_dict, sort_keys = True, indent = 2, ensure_ascii=True))

However, in one particular case, there were some errors writing non-unicode data to json.

但是,在一种特殊情况下,将非 unicode 数据写入 json 时出现一些错误。

回答by Graphics Noob

Pickle is great but I think it's worth mentioning literal_evalfrom the astmodule for an even lighter weight solution if you're only serializing basic python types. It's basically a "safe" version of the notorious evalfunction that only allows evaluation of basic python types as opposed to any valid python code.

Pickle 很棒,但我认为如果您只是序列化基本的 Python 类型,那么我认为值得literal_evalast模块中提及一个更轻量级的解决方案。它基本上是臭名昭著的eval函数的“安全”版本,它只允许评估基本的 Python 类型,而不是任何有效的 Python 代码。

Example:

例子:

>>> 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

One benefit is that the serialized data is just python code, so it's very human friendly. Compare it to what you would get with pickle.dumps:

一个好处是序列化数据只是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.

The downside is that as soon as the the data includes a type that is not supported by literal_astyou'll have to transition to something else like pickling.

缺点是,一旦数据包含不受支持的类型,literal_ast您就必须过渡到其他类型,例如酸洗。

回答by yoyo

Ifyou fully trust the string and don't care about python injection attacksthen this is very simple solution:

如果您完全信任该字符串并且不关心python 注入攻击,那么这是一个非常简单的解决方案:

d = { 'method' : "eval", 'safe' : False, 'guarantees' : None }
s = str(d)
d2 = eval(s)
for k in d2:
    print k+"="+d2[k]

If you're more safety conscious then ast.literal_evalis a better bet.

如果您有更多的安全意识,那么这ast.literal_eval是一个更好的选择。

回答by Przemek D

One thing jsoncannot do is dictindexed with numerals. The following snippet

json不能做的一件事是dict用数字索引。以下片段

import json
dictionary = dict({0:0, 1:5, 2:10})
serialized = json.dumps(dictionary)
unpacked   = json.loads(serialized)
print unpacked[0]

will throw

会扔

KeyError: 0

Because keys are converted to strings. cPicklepreserves the numeric type and the unpacked dictcan be used right away.

因为键被转换为字符串。cPickle保留数字类型,解压后dict可以立即使用。