如何以人类可读的方式将Python字典序列化为文本?

3
我有一个Python的dict,其中键和值是字符串、整数以及其他的字典和元组(JSON不支持这些数据结构)。我想将它保存到文本文件中,并从文件中读取。
基本上,我想要与内置的print相对应的read函数(就像在Lisp中一样)。
限制条件:
  1. 文件必须可读(因此pickle不能使用)。
  2. 无需检测循环引用。
有比json更好的方法吗?

4
你认为什么能比JSON更好? - BrenBarn
@BrenBarn:readprint相匹配。 - sds
老实说,JSON 就是你的答案,这也是它在过去 5 年中占据主导地位的原因。JSON 有哪些可读性问题?有大量的 JSON 缩进和格式化工具 - 使用它们可以使其易于阅读。JSON 也非常高效。 - smci
@smci:是的,我恐怕必须坚持使用JSON。 - sds
@sds:说实话,这太棒了。只需找到一个你喜欢的漂亮缩进/格式化工具,将其与.json文件类型关联起来,你就再也不会回头了。有大量快速高效的json库可供选择。 "人类可读性"只是一种心理障碍。当我第一次看到它时,我也有同样的反应。 - smci
显示剩余2条评论
2个回答

9
你可以在 dict 上使用 repr(),然后读取它并使用 ast.literal_eval() 解析它。它和 Python 本身一样易于阅读。
例如:
In [1]: import ast

In [2]: x = {}

In [3]: x['string key'] = 'string value'

In [4]: x[(42, 56)] = {'dict': 'value'}

In [5]: x[13] = ('tuple', 'value')

In [6]: repr(x)
Out[6]: "{(42, 56): {'dict': 'value'}, 'string key': 'string value', 13: ('tuple', 'value')}"

In [7]: with open('/tmp/test.py', 'w') as f: f.write(repr(x))

In [8]: with open('/tmp/test.py', 'r') as f: y = ast.literal_eval(f.read())

In [9]: y
Out[9]:
{13: ('tuple', 'value'),
 'string key': 'string value',
 (42, 56): {'dict': 'value'}}

In [10]: x == y
Out[10]: True

你可以考虑使用pprint模块来获得更友好的格式化输出。

2
值得注意的是,simplejson 比本方法快几个数量级,尽管本方法比朴素的 json 快一点。 - Joran Beasley
2
@JoranBeasley 很好知道。我想不出还有什么比JSON更容易实现且同样易读的了。 - user108471
1
考虑到 JSON 无法处理元组键,这似乎是唯一的答案。谢谢。 - sds
如果 repr() 的输出对您来说不够美观,您可能还想考虑使用 pprint 模块中的 pprint() 函数,该函数旨在以更可读的方式漂亮地打印Python对象。pprint() 的输出同样可以轻松地被 ast.literal_eval() 解析。 - user108471

1
老实说,json就是你的答案[编辑:只要键是字符串,没有看到有关使用字典作为键的部分],这就是它在过去5年中成为主流的原因。json有什么可读性问题吗?有大量的json缩进、美化工具、浏览器插件[1][2] - 使用它们,它肯定是人类可读的。json(/simplejson)也非常高效(C实现),它可以扩展,并且可以串行处理,而AST方法则不能做到(为什么要另辟蹊径并破坏可扩展性?)。
这似乎也是100%回答你的人的共识...每个人都不可能错;-) XML已死,好了结。
  1. 我如何美化JSON?和无数其他问题
  2. 浏览器JSON插件

抱歉,"json是你的答案"是胡说八道。 - sds
@sds:你需要解释为什么,不能只发一个脏话。就我个人而言,我尝试了几种不同的格式,直到最终不情愿地得出了相同的结论。这是有非常充分的理由的(更快的解析、更好的性能、标准化、大量第三方工具/实用程序/库)。 - smci
@sds 你需要表达一个更好的方法:使用OP的AST方法还是其他方法? - smci
该链接明确解释了json无法序列化相当多的对象。 - sds
不,它不取决于我的实际数据。“序列化”意味着通用性。这意味着任何可以有意义地保存和恢复的对象都应该被无缝地处理(例如,我没有要求保存/恢复流的能力)。 - sds
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接