【轉】如何美觀地打印 Python 對象?

pprint 是「pretty printer」的簡寫,「pretty」的含義是「漂亮的、美觀的」,還有表示「至關地」的程度語氣,所以它的含義即是:(至關)美觀的打印。html

這是個至關簡單卻有用的模塊,主要用於打印複雜的數據結構對象,例如多層嵌套的列表、元組和字典等。python

先看看 print() 打印的一個例子:git

mylist = ["Beautiful is better than ugly.", "Explicit is better than implicit.", "Simple is better than complex.", "Complex is better than complicated."] print(mylist) # 結果以下: ['Beautiful is better than ugly.', 'Explicit is better than implicit.', 'Simple is better than complex.', 'Complex is better than complicated.']

這是一個簡單的例子,所有打印在一行裏。github

想象一下,若是對象中的元素是多層嵌套的內容(例如複雜的 Json 數據),或者有超多的元素(例如在列表中存了不少 URL 連接),再打印出來會是怎樣?markdown

那確定是一團糟的,很差閱讀。數據結構

使用 pprint 模塊的 pprint() 替代 print(),能夠解決以下痛點:函數

  • 設置合適的行寬度,做適當的換行
  • 設置打印的縮進、層級,進行格式化打印
  • 判斷對象中是否出現無限循環,並優化打印內容

 

一、簡單使用post

語法:pprint(object, stream=None, indent=1, width=80, depth=None, *,compact=False)優化

默認的行寬度參數爲 80,當打印的字符(character)小於 80 時,pprint() 基本上等同於內置函數 print(),當字符超出時,它會做美化,進行格式化輸出:spa

import pprint # 打印上例的 mylist pprint.pprint(mylist) # 打印的元素是換行的(由於超出80字符): ['Beautiful is better than ugly.', 'Explicit is better than implicit.', 'Simple is better than complex.', 'Complex is better than complicated.']

二、設置縮進爲 4 個空格(默認爲1)

pprint.pprint(mylist, indent=4) [ 'Beautiful is better than ugly.', 'Explicit is better than implicit.', 'Simple is better than complex.', 'Complex is better than complicated.']

三、設置打印的行寬

mydict = {'students': [{'name':'Tom', 'age': 18},{'name':'Jerry', 'age': 19}]} pprint.pprint(mydict) # 未超長: {'students': [{'age': 18, 'name': 'Tom'}, {'age': 19, 'name': 'Jerry'}]} pprint.pprint(mydict, width=20) # 超長1: {'students': [{'age': 18, 'name': 'Tom'}, {'age': 19, 'name': 'Jerry'}]} pprint.pprint(mydict, width=70) # 超長2: {'students': [{'age': 18, 'name': 'Tom'}, {'age': 19, 'name': 'Jerry'}]}

四、設置打印的層級(默認全打印)

newlist = [1, [2, [3, [4, [5]]]]] pprint.pprint(newlist, depth=3) # 超出的層級會用...表示 [1, [2, [3, [...]]]]

五、優化循環結構的打印

當列表或其它數據結構中出現循環引用時,要完整打印出全部內容是不可能的。

因此 print 做了簡化處理,就像上例同樣,只打印外層的殼,而不打印內層循環的東西。

這種處理方式是簡化了,但沒有指出是誰致使了循環,還容易看漏。

pprint() 方法做了改進,遇到無限循環結構時,會表示成<Recursion on typename with id=number> 的格式。

還有個 saferepr() 方法,也是這樣優化,並且返回的是個字符串:

newlist = [1, 2] newlist.insert(0, newlist) # 列表元素指向列表自身,形成循環引用 # 直接 print 的結果是:[[...], 1, 2] pprint.pprint(newlist) # [<Recursion on list with id=1741283656456>, 1, 2] pprint.saferepr(newlist) # '[<Recursion on list with id=1741283656456>, 1, 2]'

六、判斷是否出現循環結構

有兩個方法能夠判斷一個對象中是否出現無限循環:

pprint.isrecursive(newlist)
# True pprint.isreadable(newlist) # False

isreadable() 除了能像 isrecursive() 同樣判斷循環,還能判斷該格式化內容是否可被 eval() 重構。

以上就是 pprint 模塊的快捷入門介紹,除此以外,還有 pformat() 方法、PrettyPrinter 類,以及某些參數的使用等內容,我以爲沒有大用,就很少說了。

如若感興趣,你可查閱:

最後,還有兩個小小的點:

一、用 pprint() 替換 print() 的技巧

在不考慮 print() 函數自己的參數的狀況下,能夠在引入 pprint 模塊後,寫上 「print = pprint.pprint」,令 print() 起到改頭換面的效果:

import pprint print = pprint.pprint mylist = ["Beautiful is better than ugly.", "Explicit is better than implicit.", "Simple is better than complex.", "Complex is better than complicated."] print(mylist) # 可對比本文開頭的例子 ['Beautiful is better than ugly.', 'Explicit is better than implicit.', 'Simple is better than complex.', 'Complex is better than complicated.']

二、國人開發的 beeprint

國內某位 pan 同窗在 Github 開源了個beeprint,明顯是對標 pprint 的。

項目地址:https://github.com/panyanyany/beeprint

它優化了字典對象的打印,對於從其它語言轉過來的同窗而言(例如 Java),這是個福音:

它還優化了長文本的打印,支持自定義對象的打印,看起來不錯。

可是,其它功能不夠齊全,並且做者中止維護兩年了,荒廢已久……

整體而言,pprint 算是 print() 的輕量級替代,簡單實用,極其方便(畢竟是標準庫),文檔豐富而有保障。

因此,若想要打印美觀易讀的數據,這個 pprint 標準庫,不妨一試哦。

 

 

原文地址:http://www.javashuo.com/article/p-hvyunsrl-du.html

相關文章
相關標籤/搜索