

如何美观地打印 Python 对象?这个标准库可以简单实现
source link: https://www.tuicool.com/articles/rqINj2i
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前不久,我写了一篇文章回顾 Python 中 print 的发展历史 ,提到了两条发展线索:
- 明线:早期的 print 语句带有 C 和 Shell 的影子,是个应用程序级的 statement,在最初十几年里,经历过 PEP-214 和 PEP-259 的改进;再到 2009 年的大版本 3.0,由语句改成了 print() 函数,还在 3.3 版本,做过一次功能增强,最终上升成为一等的内置函数。
- 暗线:介绍了 print 的竞争对手们,像传统的日志模块 logging、调试模块 pdb、主流 IDE 的调试功能,以及后起之秀 PySnooper,它们瞄准着 print 的位置,摩拳擦掌,虎视眈眈。
本文依然跟 print 相关,想介绍的是标准库中的 pprint
模块。
(未经授权,请勿转载。文章首发于: https://mp.weixin.qq.com/s/d1dQH1Fqaj_U3AXKYluhSw )
pprint 是“pretty printer”的简写,“pretty”的含义是“漂亮的、美观的”,还有表示“相当地”的程度语气,因此它的含义便是:(相当)美观的打印。
这是个相当简单却有用的模块,主要用于打印复杂的数据结构对象,例如多层嵌套的列表、元组和字典等。
先看看 print() 打印的一个例子:
mylist = ["Beautiful is better than ugly.", "Explicit is better than implicit.", "Simple is better than complex.", "Complex is better than complicated."] print(mylist) # 结果如下: ['Beautiful is better than ugly.', 'Explicit is better than implicit.', 'Simple is better than complex.', 'Complex is better than complicated.']
这是一个简单的例子,全部打印在一行里。
想象一下,如果对象中的元素是多层嵌套的内容(例如复杂的 Json 数据),或者有超多的元素(例如在列表中存了很多 URL 链接),再打印出来会是怎样?
那肯定是一团糟的,不好阅读。
使用 pprint 模块的 pprint() 替代 print(),可以解决如下痛点:
- 设置合适的行宽度,作适当的换行
- 设置打印的缩进、层级,进行格式化打印
- 判断对象中是否出现无限循环,并优化打印内容
1、简单使用
语法:pprint(object, stream=None, indent=1, width=80, depth=None, *,compact=False)
默认的行宽度参数为 80,当打印的字符(character)小于 80 时,pprint() 基本上等同于内置函数 print(),当字符超出时,它会作美化,进行格式化输出:
import pprint # 打印上例的 mylist pprint.pprint(mylist) # 打印的元素是换行的(因为超出80字符): ['Beautiful is better than ugly.', 'Explicit is better than implicit.', 'Simple is better than complex.', 'Complex is better than complicated.']
2、设置缩进为 4 个空格(默认为1)
pprint.pprint(mylist, indent=4) [ 'Beautiful is better than ugly.', 'Explicit is better than implicit.', 'Simple is better than complex.', 'Complex is better than complicated.']
3、设置打印的行宽
mydict = {'students': [{'name':'Tom', 'age': 18},{'name':'Jerry', 'age': 19}]} pprint.pprint(mydict) # 未超长: {'students': [{'age': 18, 'name': 'Tom'}, {'age': 19, 'name': 'Jerry'}]} pprint.pprint(mydict, width=20) # 超长1: {'students': [{'age': 18, 'name': 'Tom'}, {'age': 19, 'name': 'Jerry'}]} pprint.pprint(mydict, width=70) # 超长2: {'students': [{'age': 18, 'name': 'Tom'}, {'age': 19, 'name': 'Jerry'}]}
4、设置打印的层级(默认全打印)
newlist = [1, [2, [3, [4, [5]]]]] pprint.pprint(newlist, depth=3) # 超出的层级会用...表示 [1, [2, [3, [...]]]]
5、优化循环结构的打印
当列表或其它数据结构中出现循环引用时,要完整打印出所有内容是不可能的。
所以 print 作了简化处理,就像上例一样,只打印外层的壳,而不打印内层循环的东西。
这种处理方式是简化了,但没有指出是谁导致了循环,还容易看漏。
pprint() 方法作了改进,遇到无限循环结构时,会表示成 <Recursion on typename with id=number>
的格式。
还有个 saferepr() 方法,也是这样优化,而且返回的是个字符串:
newlist = [1, 2] newlist.insert(0, newlist) # 列表元素指向列表自身,造成循环引用 # 直接 print 的结果是:[[...], 1, 2] pprint.pprint(newlist) # [<Recursion on list with id=1741283656456>, 1, 2] pprint.saferepr(newlist) # '[<Recursion on list with id=1741283656456>, 1, 2]'
6、判断是否出现循环结构
有两个方法可以判断一个对象中是否出现无限循环:
pprint.isrecursive(newlist) # True pprint.isreadable(newlist) # False
isreadable() 除了能像 isrecursive() 一样判断循环,还能判断该格式化内容是否可被 eval() 重构。
以上就是 pprint 模块的快捷入门介绍,除此之外,还有 pformat() 方法、PrettyPrinter 类,以及某些参数的使用等内容,我觉得没有大用,就不多说了。
如若感兴趣,你可查阅:
- 官方介绍: https://docs.python.org/zh-cn/3/library/pprint.html
- 源码地址: https://github.com/python/cpython/blob/3.7/Lib/pprint.py
最后,还有两个小小的点:
1、用 pprint() 替换 print() 的技巧
在不考虑 print() 函数本身的参数的情况下,可以在引入 pprint 模块后,写上 “print = pprint.pprint”,令 print() 起到改头换面的效果:
import pprint print = pprint.pprint mylist = ["Beautiful is better than ugly.", "Explicit is better than implicit.", "Simple is better than complex.", "Complex is better than complicated."] print(mylist) # 可对比本文开头的例子 ['Beautiful is better than ugly.', 'Explicit is better than implicit.', 'Simple is better than complex.', 'Complex is better than complicated.']
2、国人开发的 beeprint
国内某位 pan 同学在 Github 开源了个 beeprint
,明显是对标 pprint
的。
项目地址: https://github.com/panyanyany/beeprint
它优化了字典对象的打印,对于从其它语言转过来的同学而言(例如 Java),这是个福音:
它还优化了长文本的打印,支持自定义对象的打印,看起来不错。
但是,其它功能不够齐全,而且作者停止维护两年了,荒废已久……
总体而言,pprint 算是 print() 的轻量级替代,简单实用,极其方便(毕竟是标准库),文档丰富而有保障。
所以,若想要打印美观易读的数据,这个 pprint 标准库,不妨一试哦。
作者简介:豌豆花下猫,生于广东毕业于武大,现为苏漂程序员,有一些极客思维,也有一些人文情怀,有一些温度,还有一些态度。公众号:「Python猫」(python_cat)

公众号【 Python猫 】, 本号连载优质的系列文章,有喵星哲学猫系列、Python进阶系列、好书推荐系列、技术写作、优质英文推荐与翻译等等,欢迎关注哦。
Recommend
-
99
设计实战!一个美观又易用的食谱APP要如何设计?
-
39
有问题,上知乎。知乎是中文互联网知名知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。
-
61
有问题,上知乎。知乎是中文互联网知名知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。
-
45
XPopup 功能强大,UI简洁,交互优雅的通用弹窗!可以替代Dialog,PopupWindow,PopupMenu,BottomSheet等组件,自带十几种效果良好的动画, 支持完全的UI和动画自定义! 编写本库的初衷有以下几点: 项目有这样常
-
42
Cleanmock - 简洁美观的网页、移动端 mockups 原型设计工具 - NEXT
-
45
钱迹 - 一款简洁美观,无广告、无后台、无理财的 “三无” 记账 App - NEXT
-
7
如何用Python的标准print函数打印一个彩色的围棋局面?
-
7
⌈随笔⌋ Beats如何牺牲美观性换取易用性 这些年只用过 Beats,纵使音质口碑一般。在家 Studio Wireless,在外 BeatsX。后者随时随意挂在脖子上,需用时立刻戴起来入耳,简...
-
5
如何清晰美观地展现 Linux 文件系统-51CTO.COM 如何清晰美观地展现 Linux 文件系统 作者:聆听世界的鱼 2022-02-24 09:39:22 lfs 是一个类似于 df 命令的小工具,用于在 Linux 上以清晰美观的表格形式生成文...
-
12
Python标准库: pickle模块——对象序列化和反序列化 May 30, 2018 工具,
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK