首頁  >  文章  >  後端開發  >  使用Python時多少有人走過的坑!避險!

使用Python時多少有人走過的坑!避險!

coldplay.xixi
coldplay.xixi轉載
2020-09-29 18:01:222042瀏覽

使用Python時多少有人走過的坑!避險!

毫無疑問,print 函數是我們日常最常用的函數,無論是格式化輸出或列印中間變數進行偵錯,幾乎沒有print 接不了的活兒。

但是上一次阿醬就差點被 print 給坑了。

坑從哪裡來

最初是想要為自己的一個命令列小工具增加一個進度顯示功能,於是用了threading 模組來實作多線程,一個執行緒用於執行實際的邏輯,另一個執行緒用於列印當前進度。

使用Python時多少有人走過的坑!避險!
點擊並拖曳以移動

根據我們

多年使用命令行的經驗,一般打印進度都是在行內打印,而Python的print

則會默認在結尾打印一個換行符,這就十分不美了。

不過好在,print 也提供了介面來改變列印的結尾字符,透過指定printend 參數,即可改變print 的列印結果。

所以我就哼噠哼噠地開乾了,把打印進度的print("#") 呼叫改為print("#", end="" )

類似這樣:

使用Python時多少有人走過的坑!避險!
#點擊並拖曳以移動
##哪成想,這麼一改卻出了大問題:進度沒辦法即時印了。

使用Python時多少有人走過的坑!避險!
點擊並拖曳以移動
也就是說,本來應該在程式執行期間​​,挨個印出來的

# 號不再是聽話的、可愛的# 號了,而是在整個程式執行完成之後一次性輸出到控制台中。

它長大了,

也變醜了

使用Python時多少有人走過的坑!避險!
點擊並拖曳以移動
那我要你有何用?

使用Python時多少有人走過的坑!避險!
點擊並拖曳以移動
啥問題呢?

一開始阿醬以為是多線程出了問題,傻乎乎地到處找資料來「佐證」自己的各種猜測——事後想來實在太傻了,以至於現在說起還是會哈哈哈

使用Python時多少有人走過的坑!避險!
點選並拖曳以移動
這件事給我們的教訓是: 千萬不要自以為是,而應踏實地解決問題,虛心對待每個細節。

實際上,之所以我們看不到即時的輸出,就是因為我們改變了

print 的結尾字元。

為了盡量減少I/O操作,Python存在一個這樣的機制:盡量將輸出字元快取起來,當遇到字串結束、換行符或強制刷新緩衝區時,才會一次將緩衝區的內容輸出到對應的流。

——而我們改掉的地方,就是把

print 預設的換行符號去掉了,所以原本每一個print 都會觸發一次緩衝區刷新,變成了現在一直觸發不了緩衝區刷新,直到程式結束觸發一次。

好嘛,知道了啥問題,我們又吭哧吭哧找資料,聽說

sys.stdout.flush 可以強制觸發標準輸出緩衝區的刷新,於是在print 後面,緊跟著又加上了sys.stdout.flush()

誒?還真好了?

使用Python時多少有人走過的坑!避險!
點擊並拖曳以移動
這些可都是知識點,快記下來記下來,要考的

使用Python時多少有人走過的坑!避險!
點擊並拖曳以移動

讓我們查看print 的官方文檔,其原型為:

使用Python時多少有人走過的坑!避險!
點擊並拖曳以移動

根據其下的描述,Python中print 的輸出是否進行緩衝,取決於兩個參數: fileflush

file 的型別有的需要緩衝,例如 sys.stdout ;而有的則不需要緩衝,例如 sys.stderr

對於flush 參數,當其值為False (預設)時,是否緩衝依賴file ;而當其值為True 時,則會強制刷新緩衝區。

我們把範例呼叫中的print 呼叫修改一下:

使用Python時多少有人走過的坑!避險!
點擊並拖拉以移動
使用Python時多少有人走過的坑!避險!
點擊並拖曳以移動

同樣可以實現進度的即時列印。

此外,還有一種方法,在呼叫程式時增加一個-u 選項,也可以實作緩衝區的即時刷新:

使用Python時多少有人走過的坑!避險!
點擊並拖曳以移動
使用Python時多少有人走過的坑!避險!
#點擊並拖曳以拖曳以移動

當然這種方法就不太推薦了,畢竟不能對程式的使用者作任何預設。

總結

本文是阿醬的一次踩坑實錄,記錄了Python中一個很少有人會遇到的奇葩問題。

總的來說,要成為一個真正的Python程式設計師,只是單純掌握基本語法和一些奇技淫巧是遠遠不夠的,還是需要對Python本身有一定的了解。

畢竟,劍客如果不熟悉自己的劍,又該如何行走江湖呢?

相關免費學習推薦:python影片教學

#

以上是使用Python時多少有人走過的坑!避險!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除