對於 bug 鋪天蓋地的 Python 程序,該如何高效的調試?

點擊藍色「Python空間」關注我丫程序員

加個「星標」,天天一塊兒快樂的學習web



無論用什麼語言在編寫程序的時候,總會出現形形色色的 bug,因爲程序員常常被玩壞,各類屬於程序員的「俚語」也被大衆熟知,出現了 bug 估計連我隔壁老王的 三姨媽的四表舅的遠房表姐的鄰居的同窗的妹夫的外婆的還在喝奶的侄女都知道要 debug,問題是 debug 說的容易,如何「de」,估計不少人仍是一腦門兒


在遙遠的 n 年前,那個時候我仍是個憨批,阿不,是個蒟蒻。那個時候我在 寫 C 語言(個人第一門編程語言)的時候,出現了 bug 用 printf 查錯,可能寫的程序又多又爛,printf 被我用的爐火純青,出神入化,debug 的速度比我洗腦袋的時間還要快上一分。


Python 的手段比當年 C 的手段還多了很多,除了「打印」(print)之外,還能夠配合 assert、log 來分析錯誤緣由,再加上單元測試效率仍是四顆星的。可是這種方式,更多的適合「自娛自樂」的狀況。啥是自娛自樂,就是這段代碼是你寫的,你知道代碼什麼意思,並且最好這個代碼比較...短。


後來入了 ACM 的坑,有了能讓我抱大腿的隊友,成了一位光榮的划水選手。我不能只看本身的代碼了,個人 printf 如陷入了泥沼中,步履維艱,在「大腿」鄙視的眼神中,被安利了「單步調試」,它的絲滑讓我欲罷不能,只能用這兩個字形容:


由於對它的迷戀,在學 Python 的第一時間,我就查瞭如何調試 Python 代碼,我發現 Python 對於 debug 的支持仍是很給勁的,經常使用的有兩種: pdb 調試和斷點 + 單步調試

0x00 pdb 調試

pdb 是 Python 自帶的庫,爲 Python 提供了一種交互式的源碼調試功能,包含當前調試器應有的功能,包括設置斷點、單步調試、查看源碼等。其實若是你以前學過 C/C++ 的話,你可能知道 gdb 這個命令行調試工具,若是你以前用過 gdb,那麼恭喜你你能夠直接用 pdb 了,由於兩個用法是同樣的。
編程


其實還有一個開源的 Python 調試器 -- ipdb,它和 pdb 的接口是同樣的,可是 ipdb 相比於 pdb 多了語法高亮,tab 自動補全等友好功能,在易用性方面作了很大的改進,這個感受就和 Python 和 IPython 同樣。微信


關於 pdb 調試和 ipdb 調試的用法,我在之前的文章中也寫過,感興趣的能夠看一下:app


Python 調試器,一個優秀開發人員的必備技能包。
編程語言


0x01 斷點 + 單步調試編輯器


這個更多的是在圖形界面下的調試,不少 IDE 都支持 Python,調試功能都很完善,這裏我主要介紹在 Pycharm 下的調試,畢竟 Pycharm 能夠說是當前最好用的 Python IDE。工具


斷點
單元測試


在斷點這個地方,主要分爲兩步:「找斷點」「打斷點」
學習


找斷點,就是你想調試的代碼塊的第一行代碼便可,也就是一個斷點接足夠了,找到之後就能夠打斷點了。可能有同窗就有這麼一個問題:


我都不知道是哪部分出了問題,我哪知道我要調試哪段代碼?



好像有點道理,不要慌,問題不大。首先你在關鍵的代碼位置上 print,而後經過分析 print 的值來縮小範圍,固然這個過程你要穩住,可能須要重複屢次,通常這樣就能夠將範圍縮小到一個比較完整的功能代碼塊中,而後就打斷點好了。


因此知道爲啥叫「打」斷點了吧,誰讓它那麼難找...



下面來講打斷點的方法,就是單擊目標代碼的行號右邊空白處,而後出現一個紅紅的圈,就證實打斷點成功了,請看下圖:



單步調試


斷點打完了,那麼就該「單步調試」了。


調試的方法很是簡單,就是在當前的 py 文件內部點鼠標右鍵,單擊「Debug xxx」(xxx 是 py 文件名):



此時 Pycharm 會調出一個控制檯,這個控制檯大概分爲顯示內容的區域和工具區域:



其中工具區域有兩個面板:Debugger 和 Console。對於 Debugger 面板,它的內容是在內容區域顯示,顯示的爲程序執行過程當中的變量及細節;Console 面板則是輸出數據顯示的位置。


對於咱們的代碼,若是到調試狀態,該行代碼就處於一個凍結的狀態,在點擊"按步操做"以後,纔會一行一行代碼執行。


主要用到 Step Over 這個按鈕:



單擊 Step Over 這個按鈕以後,代碼會跳到下一行,這時表明着第一行代碼已經執行完畢,此時在 Debugger 面板顯示以下:



在上圖中咱們看到了在程序運行狀態下變量中的值,這樣一來,程序的運行過程對於咱們來講就變的很透明瞭,咱們就能夠看到在運行過程當中這個值是否是咱們指望的值,若是不是,那這就是出 Bug 的緣由。

而後咱們繼續單擊 Step Over 按鈕,一直到最後一步:



而後你會在 Debugger 面板內看到全部的變量及其值和類型,而後咱們再來單擊 Step Over 按鈕,讓咱們來看一下發生了什麼:



天吶個天,Debugger 面板中什麼都沒了...


不要慌,這都是有原因的。 還記得在那好久好久之前,我給你們講的變量麼...


忘記沒事,聽我再慢慢道來...

這要從盤古開天闢地,阿不,女媧補天提及...

變量是啥子呢? 咱們知道變量是存儲數據的。 可是變量它住在哪呢? 住在內存裏,固然這個住只能是暫住,畢竟內存就這麼大點兒,都賴着不走那內存很快就滿了。 它臨時存儲再內存當中,啥叫臨時存儲,就是到點兒了就趕你走,變量的"到點兒"就是程序執行完的時候,那個時候內存中的變量就沒了,因此咱們就什麼也看不到了。

Debugger 面板完事兒了,下面就該看 Console 面板了:


當咱們切換到 Console 面板的時候,咱們看到了兩個 print 輸出的結果(兩個結果是在一步步 Step Over 的過程當中,每執行完一個 print 以後產生一個對應的結果)。

使用斷點 + 單步調試的方法能夠很完美的展現程序"自上而下"執行這一特徵,同時能夠查看程序的執行細節、變量類型和數據輸出這些內容,能夠更快速的找出 bug,理解程序運行的過程,省時省力又省心。

文章中我用了很簡單的一段代碼來演示在 Pycharm 中如何打斷點,如何單步調試,其實對於複雜的程序,也是由一個個簡單的代碼塊堆積起來,掌握了方法,多寫 bug,阿不,多用調試方法,相信隨着這個過程的進行,你必定能成爲一個 debug 小能手。


黑客們會用到哪些Python技術?

你離搞懂遞歸等概念只差這 10 張動圖的距離

千萬不要一生靠技術生存。

GitHub 標星 6.2k+!前 Google 工程師出品,最佳開發工具大全!



👆掃描上方二維碼便可關注

本文分享自微信公衆號 - Python空間(Devtogether)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索