如何在iPython中漂亮地打印字典

3

我目前正在使用RethinkDB,它有一个漂亮的Web UI和一个数据浏览器,允许用户像这样打印出数据库的内容:

enter image description here

请注意每个键值对都从新的一行开始,键和值(大多数情况下)颜色不同。相比之下,如果我在iPython中打印出相同的内容,则会得到一个几乎无法辨认的结果:

enter image description here

如果我遍历游标并print每个项目,情况会稍微改善,如下所示:

enter image description here

然而,这需要更多的打字,并且仍然不如RethinkDB web UI看起来好。也许有一个iPython插件可以安装以改善打印输出的外观吗?
(我看了一下pprint,但这似乎只控制文本的位置而不是它的颜色)。

关于您对PPrint的评论:缩进是否不足够?删除字符串的Unicode也很困难:https://dev59.com/8nRA5IYBdhLWcg3w_C4w - RvdK
2个回答

4
您可以使用 json.dumps() 方法:
import json 

for row in r.db(....).run(conn):
    print(json.dumps(row, indent=4))

尽管这种方法不能按照排序顺序显示键,就像示例中看到的那样,但这可能已经满足你的需求。正如 @coder 指出的那样,你可以使用json.dumps()并指定参数sort_keys=True来对键进行排序。
for row in r.db(....).run(conn):
    print(json.dumps(row, indent=4, sort_keys=True))

也有可能直接打印对象(尚未测试):

print(json.dumps(r.db(....).run(conn), indent=4, sort_keys=True)

这可能还会打印出周围的“list”对象。


为了处理不支持序列化到JSON的对象,您可以使用自定义JSONEncoder。以下是一个处理datetime.datetime对象的示例:

from datetime import datetime

class DateTimeAwareJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            tz = obj.tzname()
            return obj.ctime() + (' {}'.format(tz) if tz else '')
        return super(DateTimeAwareJSONEncoder, self).default(obj)

for row in r.db(....).run(conn):
    print(json.dumps(row, indent=4, sort_keys=True, cls=DateTimeAwareJSONEncoder))

你可以使用 datetime.strftime() 来格式化需要的日期时间字符串。

3
如果需要的话,可以使用带有参数 sort_keys=Truejson.dumps 对键进行排序。 - coder
这对于包含非 JSON 可序列化对象的字典无效,例如 Decimal - chris
@ChrisAnderson:所以为Decimal编写一个自定义的JSON编码器,就像我为datetime对象所示。 - mhawke

0

mhawke的答案有效,如果在RethinkDB的run()命令中添加关键字参数time_format="raw"。(否则,由于RethinkDB包含时区信息的对象不是JSON可序列化的,会出现TypeError错误)。结果看起来像这样:

enter image description here

这种方式更易读。稍微的缺点是epoch_time比原始时间格式更难解释。


你可以使用自定义的 JSONEncoder 来处理 datetime 对象。请参考我的更新答案。 - mhawke

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