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标准格式的格式化内容(双引号)
如果你是在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)
终于成功了,太不容易了吧。
通过上面的一番折腾,我终于实现了我梦寐以求的需求。
代价就是我整整花费了两个小时,才得以实现,而对于小白来说,可能没有信心,也没有耐心去做这样的事情。
所以我想说的是,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的写法完全一致,对于这一点不需要考虑兼容问题
本来很简单的一个观点,我为了证明pprint实现那两个需求有多么困难,花了很多的时间去研究了pprint的源码(各种处理其实还是挺复杂的),不过好在最后也能有所收获。
本文的分享就到这里,阅读本文,我认为你可以获取到三个知识点:
核心观点:Python2下不要再使用pprint
若真要使用,且有和一样的改造需求,可以参考我的实现
Python2中的print语句后居然可以加逗号
以上。希望此文能对你有帮助。
睡前人工智能共享实验室新功能上线啦!
版权声明:本站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请举报,一经查实,本站将立刻删除。