PrettyPrinter是Python 3.6 及以上版本中的一个功能强大、支持语法高亮、描述性的美化打印包。它使用了改进的Wadler-Leijen布局算法,和Haskell打印美化库中的prettyprinter以及anti-wl-pprint、 JavaScript的Prettier、Ruby的prettypreinter.rb 以及 IPython的Ipython.lib.pretty类似。Python的PrettyPrinter集以上众家之所长,并在此基础上继续改进,因此也成为目前Python最强大的美化输出工具。

以下是使用PrettyPrinter输出结果的截图:

为什么Python还需要额外的美化打印包呢?

无论是IDE还是开发者手动运行命令,将数据打印到屏幕上是程序运行过程中程序员和数值交互的最基础的界面。改进该界面有助于提升开发体验和生产效率。Python本身和第三方库都提供了一些工具来达到此目的:

  • __repr____str__两个下划线方法返回普通字符串。__repr__应该尽可能返回语法正确的Python表达式,断言判断失败及控制台计算结果打印最常用的就是该方法。由于其完全基于字符串格式化,因此并不具备美化打印的功能。
  • 标准库中的pprint模块为dicts, lists, tuples, sets, and frozensets等内置数据类型提供了美化打印的功能。它将__repr__方法应用在用户自定义的类实例上。然而,它使用了非常贪婪的布局算法,导致在很多情况下的美化打印出现问题。由于自定义的美化打印受__repr__所限制,pprint的作用也就限制于内置数据类型了。
  • 第三方库pprintpp是对pprint的改进及替代方案,也可以对输出进行优化,不过和pprint一样受限于__repr__使用的代码美化定义。
  • IPython中默认的打印模块IPython.lib.pretty的目标是pprint更进阶的替代方案。和pprint相比,它在很多方面都表现得更好:大多数情况下算法都能对输出进行美化,而且提供了针对用户自定义类型美化输出的定义工具,能和输出的其他部分实现比较好的结合。不过,为了实现你自己的美化打印方式,你需要对布局算法有所了解。另外,该API 也有一些与生俱来的副作用:调用美化打印工具将数据直接推送至布局缓冲区,不允许原始布局对数据进行初步检测。

以上所有工具都达不到我对美化打印体验的要求,因此我开始做以下几点改进:

  • 实现一个能尽可能多的美化打印的算法,即便在效率上做出一些牺牲。花十分之一秒对输出结果进行美化是非常划算的,因为当你需要在结果中寻找自己需要的数据时它将为你节约两秒钟的时间。
  • 实现一个超级简单、描述性的接口来实现用户自定义的美化打印工具。Python成员几乎不会重写__repr__方法,因为这很痛苦;几乎没有人愿意为用户定义的类型编写整齐打印规则,除非类型非常简单。
  • 实现不会在无效Python语法上中断的语法高亮显示。并不是所有__repr__方法都会返回有效的语法,一旦发生语法错误会打断正常的语法高亮。

新的代码美化包的使用体验令我非常惊讶。算法运行的很出色,效率也满足需求。而用户自定义美化规则的方法也很简单,仅仅需要了解两个描述性的函数 register_pretty和pretty_call即可。语法高亮看上去非常漂亮,且不会被无效语法处中断。特别是语法高亮,会使你很难再回到普通的美化打印工具,它大大提升了程序员的开发体验。

最有趣的改进是描述性API,下面是它的工作原理。

简单、描述性的API

在PrettyPrinter中定义输出美化方法主要基于(创建)函数调用。所有非字符的Python值都需要用函数结果表示。该库的主力函数是pretty_call, 它允许你来描述PrettyPrinter应该输出何种类型的函数调用。下面就是pretty_call调用的一个例子:

PrettyPrinter处理原始布局的过程类似于以下语句:

(第一个参数ctx允许用户控制案例中[5,3,6,1]列表中嵌套的数据,reverse参数的True值依据此进行渲染。大部分情况都直接使用默认值即可。)

上面介绍了如何使用Pretty_call,接下来定义我们自己的类型。

使用register_pretty修饰符,可以为MyClass类定义美化方式:

cpprint的输出如下:

点击 the PrettyPrinter definition code for standard library types,查看更多案例。

带状态实例的表示

调用函数的一个缺陷是无法很好的表示带状态的实例。通常你想要额外输出一些信息来表示实例的状态。PrettyPrinter使用解释性评论解决了这一问题,我对这一强大的特性颇为满意。使用评论来标注Python值(或者表示Python值的原始布局),该评论将神奇的出现在输出的结果中。

假如我们定义了一个包含其连接与断开两个状态的Connection类:

如果想得到以下输出:

可以通过如下定义来实现:

结论

我非常享受将PrettyPrinter作为开发工具包的一部分。单独一篇文章只能粗略分享一些点,还有很多有趣的部分等待你去探索,强烈推荐大家尝试一下!在IPython中使用效果更佳,因为交互式解释器环境中的所有结果都可以自动使用PrettyPrinter打印输出。文档中有对该命令的设置的说明。

点击source code on GitHub查看该项目的源码,文档在documentation on http://readthedocs.io(目前可能还略显简陋)。包中内置了针对Django模型、QuerySets以及使用attrs包创建的所有类的现成的定义。因此如果你恰好也用到了其中的某个,毫无疑问你会想马上试试它的!

英文原文:https://tommikaikkonen.github.io/introducing-prettyprinter-for-python/
译者:woody

python 打印类型_让Python输出更漂亮:PrettyPrinter相关推荐

  1. python打印长方形_利用python打印出菱形、三角形以及矩形的方法实例

    前言 本文主要给大家介绍了关于利用python打印出菱形.三角形以及矩形的相关内容,分享出来供大家参考学习,话不多说,来一起看看详细的介绍: 实例代码 #coding:utf-8 rows = int ...

  2. python打印星图_在python中探索地图与星图

    python打印星图 地图(map) "map(function, iterable, ...) " map(function, iterable, ...) Return an ...

  3. python打印时间_在Python中定义Main函数(第二部分)

    Main函数的最佳实践 既然您已经了解两种执行方式上的差异,那么掌握一些最佳实践方案还是很有用的.它们将适用于编写作为脚本运行的代码或者在另一个模块导入的代码. 如下是四种实践方式: 将大部分代码放入 ...

  4. python 打印文件名_在Python中打印文件名,关闭状态和文件模式

    python 打印文件名 Prerequisite: Opening, closing a file/open(), close() functions in Python 先决条件: 在Python ...

  5. python打印表格_使用 Python 打印漂亮的表格,这两项基本功你可会?

    今天给大家介绍如何在打印字符串时,规则对齐的两种方法,帮助大家在 shell 界面下输出漂亮的表格. 第一种:使用 format 先来看几个小 demo 左对齐 >>>"{ ...

  6. python 打印文件_在Python中打印word文档

    我这里有一个简单的批处理文件,它将从命令行打印word文档. "C:\Program Files\Microsoft Office\Office12\winword.exe" &q ...

  7. 用python打印倒三角形_用Python打印三角形

    打印左下直角三角形 num = input("please input your number: ") for i in range(num): for j in range(i+ ...

  8. 12月17日云栖精选夜读 | 用PrettyPrinter,让Python输出更漂亮,你值得拥有

    PrettyPrinter是Python 3.6 及以上版本中的一个功能强大.支持语法高亮.描述性的美化打印包.它使用了改进的Wadler-Leijen布局算法,和Haskell打印美化库中的pret ...

  9. 12月17日云栖精选夜读 | 用PrettyPrinter,让Python输出更漂亮,你值得拥有...

    PrettyPrinter是Python 3.6 及以上版本中的一个功能强大.支持语法高亮.描述性的美化打印包.它使用了改进的Wadler-Leijen布局算法,和Haskell打印美化库中的pret ...

最新文章

  1. 数字图像处理:腐蚀与膨胀操作
  2. OVS datapath包处理流程(二十)
  3. neo4j CQL语句
  4. 微信小程序 事件点击后如何动态增删class类名(自用,没毛病)
  5. distenct oracle_oracle中distinct的用法详解
  6. .net里面实现javascript中的 escape 和 unescape 功能
  7. java界面字体大小设置_怎样更改电脑界面的字体大小?
  8. 是否可以在网络共享磁盘上创建数据库?
  9. mysql触发器实例
  10. 微机计算机继电保护原理,微机继电保护的装置构成
  11. cad2016中选择全图字体怎么操作_PPT有哪些可以一劳永逸的操作?
  12. 【Unity】【Code】通用代码库(一)——物体的wasd移动
  13. 多线程编程warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 错误解决
  14. kotlin插件禁用导致的Android studio无法打开-mac
  15. 上传遥感图像在地图上自动加载到地图上
  16. excel职称计算机应用,2017职称计算机考试Excel辅导:工作表的编辑
  17. 瑞利、莱斯、高斯信道模型
  18. 金蝶软件工具集4.0
  19. A股股本结构历史数据查询Web API使用方法
  20. Object.setPrototypeOf 与 Object.create() 的区别

热门文章

  1. 第 19 次 CCF CSP 认证 202006-2 稀疏向量(svector)
  2. Python使用库读取数据
  3. 如何在html嵌入html网页
  4. 【实用】Pyinstaller UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xce in position解决方案
  5. keras callback中的stop_training
  6. 统计bytearray中的bitcount
  7. spring boot 使用devtools热部署
  8. 远程对象工厂设计模式
  9. asp.net MVC错误:uses 'System.Web.WebPages, Version=2.0.0.0, ....which has a higher version...
  10. Spring Cloud (断路器) Hystrix(三)