0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

让Python输出更整洁:PrettyPrinter

马哥Linux运维 来源:未知 作者:李建兵 2018-03-17 09:04 7588次阅读

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 readthedocs.io(目前可能还略显简陋)。包中内置了针对Django模型、QuerySets以及使用attrs包创建的所有类的现成的定义。因此如果你恰好也用到了其中的某个,毫无疑问你会想马上试试它的!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • python
    +关注

    关注

    56

    文章

    4812

    浏览量

    85224

原文标题:让Python输出更漂亮:PrettyPrinter

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    相关推荐

    Python 语言的发展简史

    个函数。一个Python程序员应该很容易理解这段程序。ABC语言使用冒号和缩进来表示程序块。行尾没有分号。for和if结构中也没有括号()。赋值采用的是PUT,而不是常见的等号。这些改动ABC程序
    发表于 09-28 10:14

    代码整洁之道

    代码整洁之道
    发表于 08-26 16:07

    如何边缘计算安全?

    边缘计算中的安全挑战如何边缘计算安全?可扩展的边缘安全方案
    发表于 02-26 06:36

    [代码整洁之道].(美)马丁.扫描版

    电子发烧友网站提供《[代码整洁之道].(美)马丁.扫描版.txt》资料免费下载
    发表于 02-06 16:47 0次下载

    你的 Python 代码优雅又地道

    Python社区文化的浇灌下,演化出了一种独特的代码风格,去指导如何正确地使用Python,这就是常说的pythonic。一般说地道(idiomatic)的python代码,就是指这份代码很
    的头像 发表于 03-06 10:35 3692次阅读

    代码质量和其整洁度成正比有什么道理如何进行代码整洁教材免费下载

    《代码整洁之道》是2010年1月由人民邮电出版社出版的图书,作者是马丁。本书主要讲述了代码质量与其整洁度成正比的道理,并由此揭示代码整洁之道。《代码整洁之道》讲述了一系列行之有效的
    发表于 11-28 08:00 1次下载

    如何Python输出漂亮:PrettyPrinter美化打印包使用手册

    PrettyPrinterPython 3.6 及以上版本中的一个功能强大、支持语法高亮、描述性的美化打印包。
    的头像 发表于 12-08 10:45 9036次阅读

    超简单:用PythonExcel飞起来

    超简单:用PythonExcel飞起来
    发表于 05-25 10:46 57次下载

    Python中实现简单好用的函数运算缓存

    我们即将学习的是:在Python中实现简单好用的函数运算缓存。 函数运算缓存,顾名思义就是我们可以针对指定的函数,其记住过往参数输入和返回结果,使得后续接收到相同的参数时跳过函数运算,直接返回已缓存的结果值。
    的头像 发表于 08-05 11:05 1083次阅读

    汽车成像您的汽车安全

    汽车成像您的汽车安全
    发表于 11-02 08:16 0次下载
    汽车成像<b class='flag-5'>让</b>您的汽车<b class='flag-5'>更</b>安全

    如何Python和Go互相调度

    我们曾经研究过如何Python和Go互相调度,当时发现,将Go语言写的模块打包成动态链接库,就能在Python中进行调度: 优劣互补! Python+Go结合开发的探讨 Go的优势很
    的头像 发表于 11-02 11:24 693次阅读
    如何<b class='flag-5'>让</b><b class='flag-5'>Python</b>和Go互相调度

    python输出list的每一个元素

    使用for循环来遍历列表,并输出其中的每一个元素。接下来,我将详尽、详实、细致地介绍一下Python输出列表的每一个元素的方法,希望能对你有所帮助。 首先,我们需要明确一下什么是列表。列表是一种有序的可变序列,其中可以包含任意类
    的头像 发表于 11-21 16:16 1829次阅读

    python输出换行符\n怎么用

    Python中,要输出换行符"n",可以使用print函数。print函数可以接受多个参数,并将它们打印到控制台。 下面是一个使用print函数输出换行符的简单示例: print
    的头像 发表于 11-22 10:48 2388次阅读

    python如何多行输出为一行

    Python中有多种方法可以将多行输出改为一行输出。 一种方法是使用end参数将换行符替换为其他字符。默认情况下,print函数会在输出的结尾处自动添加一个换行符,导致每个print语
    的头像 发表于 11-24 09:45 7764次阅读

    代码整洁之道-大师眼中的整洁代码是什么样

    模糊,带着这个问题,本人读完了世界软件开发大师马丁的《代码整洁之道》这本书,来了解下大师眼中的整洁代码画像是什么样的,相信能给你带来不一样的理解和感悟。 关于整洁代码,没有明确的定义,有多少程序员就有多少种定
    的头像 发表于 09-09 16:30 464次阅读
    代码<b class='flag-5'>整洁</b>之道-大师眼中的<b class='flag-5'>整洁</b>代码是什么样