使用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的輸出如下:
※選擇一本適合自己的Linux系統書籍
※思科交換機被爆「嚴重漏洞」將面臨攻擊
TAG:Linux資訊速推 |