Python|用PrettyPrinter熬词,讓Python輸出更漂亮旁钧,你值得擁有

PrettyPrinter是Python 3.6 及以上版本中的一個功能強(qiáng)大吸重、支持語法高亮、描述性的美化打印包歪今。它使用了改進(jìn)的Wadler-Leijen布局算法嚎幸,和Haskell打印美化庫中的prettyprinter以及anti-wl-pprint、 JavaScript的Prettier寄猩、Ruby的prettypreinter.rb 以及 IPython的Ipython.lib.pretty類似嫉晶。Python的PrettyPrinter集以上眾家之所長,并在此基礎(chǔ)上繼續(xù)改進(jìn)焦影,因此也成為目前Python最強(qiáng)大的美化輸出工具车遂。

以下是使用PrettyPrinter輸出結(jié)果的截圖:

Python|用PrettyPrinter封断,讓Python輸出更漂亮斯辰,你值得擁有
Python|用PrettyPrinter,讓Python輸出更漂亮坡疼,你值得擁有

為什么Python還需要額外的美化打印包呢彬呻?

無論是IDE還是開發(fā)者手動運(yùn)行命令,將數(shù)據(jù)打印到屏幕上是程序運(yùn)行過程中程序員和數(shù)值交互的最基礎(chǔ)的界面柄瑰。改進(jìn)該界面有助于提升開發(fā)體驗和生產(chǎn)效率闸氮。Python本身和第三方庫都提供了一些工具來達(dá)到此目的:

  • reprstr兩個下劃線方法返回普通字符串。repr應(yīng)該盡可能返回語法正確的Python表達(dá)式教沾,斷言判斷失敗及控制臺計算結(jié)果打印最常用的就是該方法蒲跨。由于其完全基于字符串格式化,因此并不具備美化打印的功能授翻。
  • 標(biāo)準(zhǔn)庫中的pprint模塊為dicts, lists, tuples, sets, and frozensets等內(nèi)置數(shù)據(jù)類型提供了美化打印的功能或悲。它將repr方法應(yīng)用在用戶自定義的類實例上。然而堪唐,它使用了非常貪婪的布局算法巡语,導(dǎo)致在很多情況下的美化打印出現(xiàn)問題。由于自定義的美化打印受repr所限制淮菠,pprint的作用也就限制于內(nèi)置數(shù)據(jù)類型了男公。
  • 第三方庫pprintpp是對pprint的改進(jìn)及替代方案,也可以對輸出進(jìn)行優(yōu)化合陵,不過和pprint一樣受限于repr使用的代碼美化定義枢赔。
  • IPython中默認(rèn)的打印模塊IPython.lib.pretty的目標(biāo)是pprint更進(jìn)階的替代方案。和pprint相比拥知,它在很多方面都表現(xiàn)得更好:大多數(shù)情況下算法都能對輸出進(jìn)行美化踏拜,而且提供了針對用戶自定義類型美化輸出的定義工具,能和輸出的其他部分實現(xiàn)比較好的結(jié)合举庶。不過执隧,為了實現(xiàn)你自己的美化打印方式,你需要對布局算法有所了解。
  • 另外镀琉,該API 也有一些與生俱來的副作用:調(diào)用美化打印工具將數(shù)據(jù)直接推送至布局緩沖區(qū)峦嗤,不允許原始布局對數(shù)據(jù)進(jìn)行初步檢測。

以上所有工具都達(dá)不到我對美化打印體驗的要求屋摔,因此我開始做以下幾點改進(jìn):

  • 實現(xiàn)一個能盡可能多的美化打印的算法烁设,即便在效率上做出一些犧牲〉鍪裕花十分之一秒對輸出結(jié)果進(jìn)行美化是非常劃算的装黑,因為當(dāng)你需要在結(jié)果中尋找自己需要的數(shù)據(jù)時它將為你節(jié)約兩秒鐘的時間。
  • 實現(xiàn)一個超級簡單弓熏、描述性的接口來實現(xiàn)用戶自定義的美化打印工具恋谭。Python成員幾乎不會重寫repr方法,因為這很痛苦挽鞠;幾乎沒有人愿意為用戶定義的類型編寫整齊打印規(guī)則疚颊,除非類型非常簡單。
  • 實現(xiàn)不會在無效Python語法上中斷的語法高亮顯示信认。并不是所有repr方法都會返回有效的語法材义,一旦發(fā)生語法錯誤會打斷正常的語法高亮。

新的代碼美化包的使用體驗令我非常驚訝嫁赏。算法運(yùn)行的很出色其掂,效率也滿足需求。而用戶自定義美化規(guī)則的方法也很簡單潦蝇,僅僅需要了解兩個描述性的函數(shù) register_pretty和pretty_call即可款熬。語法高亮看上去非常漂亮,且不會被無效語法處中斷护蝶。特別是語法高亮华烟,會使你很難再回到普通的美化打印工具,它大大提升了程序員的開發(fā)體驗持灰。

最有趣的改進(jìn)是描述性API盔夜,下面是它的工作原理。

簡單堤魁、描述性的API

在PrettyPrinter中定義輸出美化方法主要基于(創(chuàng)建)函數(shù)調(diào)用喂链。所有非字符的Python值都需要用函數(shù)結(jié)果表示。該庫的主力函數(shù)是pretty_call妥泉, 它允許你來描述PrettyPrinter應(yīng)該輸出何種類型的函數(shù)調(diào)用椭微。下面就是pretty_call調(diào)用的一個例子:

Python|用PrettyPrinter,讓Python輸出更漂亮盲链,你值得擁有

PrettyPrinter處理原始布局的過程類似于以下語句:

Python|用PrettyPrinter蝇率,讓Python輸出更漂亮迟杂,你值得擁有

(第一個參數(shù)ctx允許用戶控制案例中[5,3,6,1]列表中嵌套的數(shù)據(jù),reverse參數(shù)的True值依據(jù)此進(jìn)行渲染本慕。大部分情況都直接使用默認(rèn)值即可排拷。)

上面介紹了如何使用Pretty_call,接下來定義我們自己的類型锅尘。

Python|用PrettyPrinter监氢,讓Python輸出更漂亮,你值得擁有

使用register_pretty修飾符藤违,可以為MyClass類定義美化方式:

Python|用PrettyPrinter浪腐,讓Python輸出更漂亮,你值得擁有

cpprint的輸出如下:

Python|用PrettyPrinter顿乒,讓Python輸出更漂亮议街,你值得擁有

帶狀態(tài)實例的表示

調(diào)用函數(shù)的一個缺陷是無法很好的表示帶狀態(tài)的實例。通常你想要額外輸出一些信息來表示實例的狀態(tài)淆游。PrettyPrinter使用解釋性評論解決了這一問題傍睹,我對這一強(qiáng)大的特性頗為滿意。使用評論來標(biāo)注Python值(或者表示Python值的原始布局)犹菱,該評論將神奇的出現(xiàn)在輸出的結(jié)果中。

假如我們定義了一個包含其連接與斷開兩個狀態(tài)的Connection類:

Python|用PrettyPrinter吮炕,讓Python輸出更漂亮腊脱,你值得擁有

如果想得到以下輸出:

<pre style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; padding: 12px 10px; background: rgb(244, 245, 246); border: 1px solid rgb(232, 232, 232); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">Connection('http://example.com') # Status: Open
</pre>

可以通過如下定義來實現(xiàn):

Python|用PrettyPrinter,讓Python輸出更漂亮龙亲,你值得擁有

結(jié)論

我非常享受將PrettyPrinter作為開發(fā)工具包的一部分陕凹。單獨一篇文章只能粗略分享一些點,還有很多有趣的部分等待你去探索鳄炉,強(qiáng)烈推薦大家嘗試一下杜耙!在IPython中使用效果更佳,因為交互式解釋器環(huán)境中的所有結(jié)果都可以自動使用PrettyPrinter打印輸出拂盯。文檔中有對該命令的設(shè)置的說明佑女。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谈竿,隨后出現(xiàn)的幾起案子团驱,更是在濱河造成了極大的恐慌,老刑警劉巖空凸,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嚎花,死亡現(xiàn)場離奇詭異,居然都是意外死亡呀洲,警方通過查閱死者的電腦和手機(jī)紊选,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門啼止,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兵罢,你說我怎么就攤上這事族壳。” “怎么了趣些?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵仿荆,是天一觀的道長。 經(jīng)常有香客問我坏平,道長拢操,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任舶替,我火速辦了婚禮令境,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘顾瞪。我一直安慰自己舔庶,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布陈醒。 她就那樣靜靜地躺著惕橙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钉跷。 梳的紋絲不亂的頭發(fā)上弥鹦,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音爷辙,去河邊找鬼彬坏。 笑死,一個胖子當(dāng)著我的面吹牛膝晾,可吹牛的內(nèi)容都是我干的栓始。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼血当,長吁一口氣:“原來是場噩夢啊……” “哼幻赚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起歹颓,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤坯屿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后巍扛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體领跛,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年撤奸,在試婚紗的時候發(fā)現(xiàn)自己被綠了吠昭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喊括。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖矢棚,靈堂內(nèi)的尸體忽然破棺而出郑什,到底是詐尸還是另有隱情,我是刑警寧澤蒲肋,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布蘑拯,位于F島的核電站,受9級特大地震影響兜粘,放射性物質(zhì)發(fā)生泄漏申窘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一孔轴、第九天 我趴在偏房一處隱蔽的房頂上張望剃法。 院中可真熱鬧,春花似錦路鹰、人聲如沸贷洲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽优构。三九已至,卻和暖如春趣斤,著一層夾襖步出監(jiān)牢的瞬間俩块,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工浓领, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人势腮。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓联贩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捎拯。 傳聞我的和親對象是個殘疾皇子泪幌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容