毫無疑問,print
函數是我們日常最常用的函數,無論是格式化輸出或列印中間變數進行偵錯,幾乎沒有print
接不了的活兒。
但是上一次阿醬就差點被 print
給坑了。
最初是想要為自己的一個命令列小工具增加一個進度顯示功能,於是用了threading
模組來實作多線程,一個執行緒用於執行實際的邏輯,另一個執行緒用於列印當前進度。
根據我們
多年使用命令行的經驗,一般打印進度都是在行內打印,而Python的print
則會默認在結尾打印一個換行符,這就十分不美了。
不過好在,print
也提供了介面來改變列印的結尾字符,透過指定print
的end
參數,即可改變print
的列印結果。
所以我就哼噠哼噠地開乾了,把打印進度的print("#")
呼叫改為print("#", end="" )
。
類似這樣:
##哪成想,這麼一改卻出了大問題:進度沒辦法即時印了。 也就是說,本來應該在程式執行期間,挨個印出來的# 號不再是聽話的、可愛的
# 號了,而是在整個程式執行完成之後一次性輸出到控制台中。
也變醜了 。
那我要你有何用? 啥問題呢? 一開始阿醬以為是多線程出了問題,傻乎乎地到處找資料來「佐證」自己的各種猜測——事後想來實在太傻了,以至於現在說起還是會哈哈哈 這件事給我們的教訓是: 千萬不要自以為是,而應踏實地解決問題,虛心對待每個細節。 實際上,之所以我們看不到即時的輸出,就是因為我們改變了print 的結尾字元。
print 預設的換行符號去掉了,所以原本每一個
print 都會觸發一次緩衝區刷新,變成了現在一直觸發不了緩衝區刷新,直到程式結束觸發一次。
sys.stdout.flush 可以強制觸發標準輸出緩衝區的刷新,於是在
print 後面,緊跟著又加上了
sys.stdout.flush() 。
讓我們查看print
的官方文檔,其原型為:
根據其下的描述,Python中print
的輸出是否進行緩衝,取決於兩個參數: file
和flush
。
file
的型別有的需要緩衝,例如 sys.stdout
;而有的則不需要緩衝,例如 sys.stderr
。
對於flush
參數,當其值為False
(預設)時,是否緩衝依賴file
;而當其值為True
時,則會強制刷新緩衝區。
我們把範例呼叫中的print
呼叫修改一下:
同樣可以實現進度的即時列印。
此外,還有一種方法,在呼叫程式時增加一個-u
選項,也可以實作緩衝區的即時刷新:
當然這種方法就不太推薦了,畢竟不能對程式的使用者作任何預設。
本文是阿醬的一次踩坑實錄,記錄了Python中一個很少有人會遇到的奇葩問題。
總的來說,要成為一個真正的Python程式設計師,只是單純掌握基本語法和一些奇技淫巧是遠遠不夠的,還是需要對Python本身有一定的了解。
畢竟,劍客如果不熟悉自己的劍,又該如何行走江湖呢?
#相關免費學習推薦:python影片教學
以上是使用Python時多少有人走過的坑!避險!的詳細內容。更多資訊請關注PHP中文網其他相關文章!