求你了,别再使用 pprint 打印字典了

1.吐槽问题

pprint你应该很熟悉了吧?

随便在搜索引擎上搜索如何打印漂亮的字典或者格式化字符串时,大部分人都会推荐你使用这货。

比如这下面这个json字符串或者说字典(我随便在网上找的),如果不格式化美化一下,根本无法阅读。

[{"id":1580615,"name":"皮的嘛","packageName":"","iconUrl":"app//","stars":2,"size":21803987,"downloadUrl":"app//","des":"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":"不存在的","packageName":"","iconUrl":"app//","stars":2,"size":4794202,"downloadUrl":"app//","des":"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]

如果你不想看到一堆密密麻麻的字,那就使用大伙都极力推荐的pprint看下什么效果(以下在Python2中演示,Python3中是不一样的效果)。

info=[{"id":1580615,"name":"皮的嘛","packageName":"","iconUrl":"app//","stars":2,"size":21803987,"downloadUrl":"app//","des":"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":"不存在的","packageName":"","iconUrl":"app//","stars":2,"size":4794202,"downloadUrl":"app//","des":"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]frompprintimportpprintpprint(info)[{'des':'2011-2017\xe4\xbd\xa0\xe7\x9a\x84\xe9\x93\x81\xe5\xa4\xb4\xe5\xa8\x83\xe4\xb8\x80\xe7\x9b\xb4\xe5\x9c\xa8\xe8\xbf\x99\xe5\x84\xbf\xe3\x80\x82\xe4\xb8\xad\xe5\x9b\xbd\xe6\x9c\x80\xe5\xa4\xa7\xe7\x9a\x84\xe5\xae\x9e\xe5\x90\x8d\xe5\x88\xb6SNS\xe7\xbd\x91\xe7\xbb\x9c\xe5\xb9\xb3\xe5\x8f\xb0\xef\xbc\x8c\xe5\xab\xa9\xe5\xa4\xb4\xe9\x9d\x92','downloadUrl':'app//','iconUrl':'app//','id':1580615,'name':'\xe7\x9a\xae\xe7\x9a\x84\xe5\x98\x9b','packageName':'','size':21803987,'stars':2},{'des':'\xe6\x96\x97\xe9\xb1\xbc271934\xe8\xb5\xb0\xe8\xbf\x87\xe8\xb7\xaf\xe8\xbf\x87\xe4\xb8\x8d\xe8\xa6\x81\xe9\x94\x99\xe8\xbf\x87\xef\xbc\x8c\xe8\xbf\x99\xe9\x87\x8c\xe6\x9c\x89\xe6\x9c\x80\xe5\xa5\xbd\xe7\x9a\x84\xe9\xb8\xa1\xe5\x84\xbf','downloadUrl':'app//','iconUrl':'app//','id':1540629,'name':'\xe4\xb8\x8d\xe5\xad\x98\xe5\x9c\xa8\xe7\x9a\x84','packageName':'','size':4794202,'stars':2}]

好像有点效果,真的是“神器”呀。

但是你告诉我,\xe4\xbd\xa0\xe7\x9a这些是什么玩意?本来想提高可读性的,现在变成完全不可读了。

好在我懂点Python2的编码,知道Python2中默认(不带u)的字符串格式都是str类型,也是bytes类型,它是以byte存储的。

行吧,好像是我错了,我改了下,使用unicode类型来定义中文字符串吧。

info=[{"id":1580615,"name":u"皮的嘛","packageName":"","iconUrl":"app//","stars":2,"size":21803987,"downloadUrl":"app//","des":u"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":u"不存在的","packageName":"","iconUrl":"app//","stars":2,"size":4794202,"downloadUrl":"app//","des":u"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]frompprintimportpprintpprint(info)[{'des':u'2011-2017\u4f60\u7684\u94c1\u5934\u5a03\u4e00\u76f4\u5728\u8fd9\u513f\u3002\u4e2d\u56fd\u6700\u5927\u7684\u5b9e\u540d\u5236SNS\u7f51\u7edc\u5e73\u53f0\uff0c\u5ae9\u5934\u9752','downloadUrl':'app//','iconUrl':'app//','id':1580615,'name':u'\u76ae\u7684\u561b','packageName':'','size':21803987,'stars':2},{'des':u'\u6597\u9c7c271934\u8d70\u8fc7\u8def\u8fc7\u4e0d\u8981\u9519\u8fc7\uff0c\u8fd9\u91cc\u6709\u6700\u597d\u7684\u9e21\u513f','downloadUrl':'app//','iconUrl':'app//','id':1540629,'name':u'\u4e0d\u5b58\u5728\u7684','packageName':'','size':4794202,'stars':2}]

确实是有好点了,但是看到下面这些,我崩溃了,我哪里知道这是什么鬼,难道是我太菜了吗?当我是计算机呀?

u'\u6597\u9c7c271934\u8d70\u8fc7\u8def\u8fc7\u4e0d\u8981\u9519\u8fc7\uff0c\u8fd9\u91cc\u6709\u6700\u597d\u7684\u9e21\u513f'

除此之外,我们知道JSON的严格要求必须使用双引号,而我定义字典时,也使用了双引号了,为什么打印出来的为什么是单引号?我也太难了吧,我连自己的代码都无法控制了吗?

由此,我们知道了pprint带来的两个问题:

没法在Python2下正常打印中文

没法输出JSON标准格式的格式化内容(双引号)

2.解决问题打印中文

如果你是在Python3下使用,你会发现中文是可以正常显示的。

coding:utf-8frompprintimportPrettyPrintercoding:utf-8frompprintimportPrettyPrinterclassMyPrettyPrinter(PrettyPrinter):defformat(self,object,context,maxlevels,level):ifisinstance(object,unicode):return(('utf8'),True,False)(self,object,context,maxlevels,level)classMyStream():defwrite(self,text):('\'','"')info=[{"id":1580615,"name":u"皮的嘛","packageName":"","iconUrl":"app//","stars":2,"size":21803987,"downloadUrl":"app//","des":u"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":u"不存在的","packageName":"","iconUrl":"app//","stars":2,"size":4794202,"downloadUrl":"app//","des":u"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]MyPrettyPrinter(stream=MyStream()).pprint(info)

尝试执行了下,我的天,怎么是这样子的。

[{"des":2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青,"downloadUrl":"app//","iconUrl":"app//","id":1580615,"name":皮的嘛,"packageName":"","size":21803987,"stars":2},{"des":斗鱼271934走过路过不要错过,这里有最好的鸡儿,"downloadUrl":"app//","iconUrl":"app//","id":1540629,"name":不存在的,"packageName":"","size":4794202,"stars":2}]

经过一番研究,才知道是因为print函数默认会将打印的内容后面加个换行符。

那如何将使print函数打印的内容,不进行换行呢?

方法很简单,但是我相信很多人都不知道,只要在print的内容后加一个逗号就行。

就像下面这样。

知道了问题所在,再修改下代码

#coding:utf-8frompprintimportPrettyPrinterclassMyPrettyPrinter(PrettyPrinter):defformat(self,object,context,maxlevels,level):ifisinstance(object,unicode):return(('utf8'),True,False)(self,object,context,maxlevels,level)classMyStream():defwrite(self,text):('\'','"'),info=[{"id":1580615,"name":u"皮的嘛","packageName":"","iconUrl":"app//","stars":2,"size":21803987,"downloadUrl":"app//","des":u"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":u"不存在的","packageName":"","iconUrl":"app//","stars":2,"size":4794202,"downloadUrl":"app//","des":u"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]MyPrettyPrinter(stream=MyStream()).pprint(info)

终于成功了,太不容易了吧。

3.何必折腾

通过上面的一番折腾,我终于实现了我梦寐以求的需求。

代价就是我整整花费了两个小时,才得以实现,而对于小白来说,可能没有信心,也没有耐心去做这样的事情。

所以我想说的是,Python2下的pprint,真的不要再用了。

为什么我要用这么说,因为明明有更好的替代品,人生苦短,既然用了Python,当然是怎么简单怎么来咯,何必为难自己呢,一行代码可以解决的事情,偏偏要去写两个类,那不是自讨苦吃吗?(我这是在骂自己吗?

如果你愿意抛弃pprint,那我推荐你用,我保证你再也不想用pprint了。

打印中文

其实无法打印中文,是Python2引来的大坑,并不能全怪pprint。

但是同样的问题,在这里,却只要加个参数就好了,可比pprint简单得不要太多。

具体的代码示例如下:

info=[{"id":1580615,"name":"皮的嘛","packageName":"","iconUrl":"app//","stars":2,"size":21803987,"downloadUrl":"app//","des":"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":"不存在的","packageName":"","iconUrl":"app//","stars":2,"size":4794202,"downloadUrl":"app//","des":"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}](info,indent=4,ensure_ascii=False)[{"downloadUrl":"app//","iconUrl":"app//","name":"皮的嘛","stars":2,"packageName":"","des":"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青","id":1580615,"size":21803987},{"downloadUrl":"app//","iconUrl":"app//","name":"不存在的","stars":2,"packageName":"","des":"斗鱼271934走过路过不要错过,这里有最好的鸡儿","id":1540629,"size":4794202}]

的关键参数有两个:

indent=4:以4个空格缩进单位

ensure_ascii=False:接收非ASCII编码的字符,这样才能使用中文

与pprint相比可以说完胜:

两个参数就能实现所有我的需求(打印中文与双引号)

就算在Python2下,使用中文也不需要用u'中文'这种写法

Python2和Python3的写法完全一致,对于这一点不需要考虑兼容问题

4.总结一下

本来很简单的一个观点,我为了证明pprint实现那两个需求有多么困难,花了很多的时间去研究了pprint的源码(各种处理其实还是挺复杂的),不过好在最后也能有所收获。

本文的分享就到这里,阅读本文,我认为你可以获取到三个知识点:

核心观点:Python2下不要再使用pprint

若真要使用,且有和一样的改造需求,可以参考我的实现

Python2中的print语句后居然可以加逗号

以上。希望此文能对你有帮助。

睡前人工智能共享实验室新功能上线啦!

版权声明:本站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请举报,一经查实,本站将立刻删除。

相关推荐