python 程式的的除錯

JUAN425發表於2014-08-17

在這裡我們將學到如何去除錯一個python 程式。

要debug 一個Python 程式, 我們需要引入(import)內建的 module 模組pdb。

首先, 開啟notepad++, 編寫如下的程式:

# epdb1.py ----experiment with the python debugger, pdb
import pdb
a = "aaa"
pdb.set_trace()
b = "bbb"
c = "ccc"
final = a + b + c
print final 

命名為epdb1.py儲存在D:\python學習\    目錄下面:



上述的相關的程式碼解釋:

pdb.set_trace() 是在pdb 模組中定義的函式。 該函式的作用是插在我們要進行開始除錯的的那行的程式碼的前面。



接下面, cmd 開啟dos 終端, 切換到程式碼的目錄下面, 然後執行 python  epdb1.py, 具體如下:



接下來, 就開始debug了(程式執行到設定的位置, 就開始一行行執行)。

通過在提示符((Pdb))輸入n (意思是next line), 然後點選ENTER鍵及執行到下一行, 具體的如下:



最終, 我們完成了除錯的任務了。


關於除錯的tip1:

第一次需要點選點選n, 然後點選ENTER鍵,就可以了。 之後, 我們只點選ENTER 鍵, 不用再點選n,  就發現程式會繼續一步步執行的, 直至結束。


這後面的philosophy如下:


If you press ENTER without entering anything, pdb will re-execute the last command that you gave it.



關於除錯的tip2:

如何退出除錯, 我們只需要在提示符後面點選q,  然後RNTER鍵即可。 就可以quit了:




tip3: 在(pdb)提示符後面想要列印變數,例如我們先要在程式執行到某出顯示變數的值(顯示多個變數在指令p 的後面的變數用逗號分隔開),  需要的指令是p a, b, c 然後點選ENTER鍵即可。 




(向上的箭頭邊上dos 中執行的上一個命令。)


tip4 是一個注意。 也就是說最後 -> 後面顯示的程式的一行指令 值即將被執行的指令。 但是並沒有沒執行。 所以不難看出下面出現錯誤。



tip 5: 通過輸入c(意思是continue), 使得我們程式退出除錯程式的過程。 上面提到的通過輸入q 退出除錯的方式是一種粗暴的方式, 基本上使得我們的程式crash。 現在我們選擇c 的方式:



注意, 點選c使得我們的程式繼續向下執行, 直至出現下一個的除錯語句(pdb.set_trace() ). 所以, 如果我們的pdb.set_trace() 函式位於某一個loop中, 只能保證當前的迴圈不會除錯, 迴圈的下一輪仍然會繼續進入除錯狀態的。



tip6: 除錯的過程中如何檢視我們當前程式的執行到了哪一行?

答案是提示符(pdb)後面使用l 命令。 意思是listing, 該命令會列出程式中連續的的11行程式碼(如果有超過11行的程式碼)。 我們即將執行的程式碼位於這11行程式碼的正中間, 用箭頭指示(注意current line, 但是並沒有執行)。



從上圖可見, 當前執行的位置。


所以通常的pdb 的除錯的過程如下:




Stepping into subroutines… with “s” (step into)

當我們除錯一個呼叫了函式的程式的時候, 有的時候我們希望能夠在函式內部進行我們的除錯工作。 例如下面的程式 :.

# epdb2.py -- experiment with the Python debugger, pdb
import pdb

def combine(s1,s2):      # define subroutine combine, which...
    s3 = s1 + s2 + s1    # sandwiches s2 between copies of s1, ...
    s3 = '"' + s3 +'"'   # encloses it in double quotes,...
    return s3            # and returns it.

a = "aaa"
pdb.set_trace()
b = "bbb"
c = "ccc"
final = combine(a,b)
print final

在我們除錯的過程中, 我們會遇到呼叫combine 函式的語句:

final = combine(a,b)

此時,如果我們仍然在在提示符後面輸入n, 然後ENTER, 那麼python 處理這行程式的方式和其他的普通行沒有任何區別。 也就是說這個語句執行完了, 直接執行到下一行, 即列印出final。 

也就是說我們卻無法去除錯函式內的執行的每一句。

為了能夠檢視函式內部的執行細節, 我們需要在提示符後面輸入s(意思是step into), 然後就可以進入到函式內部一句一句的除錯了。

其實, 當我們執行 statements that do not involve function calls, “n” and “s” 命令做的事情是一樣的。 都是執行當前句, 跳入下一句等。. But 當時當我們execute statements that invoke functions,輸入 “s”, unlike “n”,確認, 將會step into the subroutine.本例中出現如下:

final = combine(a,b)

再次輸入“s”, 接下來就會出現函式的第一句:

def combine(s1,s2):

綜上, 除錯過程如下:


Continuing… but just to the end of the current subroutine… with “r” (return)(注意, dos 下清屏的指令為cls)

當我們在函式內部通過‘s’一步一步的執行函式內的語句, 我們檢查到了我們感興趣的程式。 此時我們不想在函式內部繼續逗留下去, 我們希望推出函式內的除錯, 繼續函式呼叫語句的下一句。 如果在(Pdb)提示符後面輸入命令c, 然後ENTER, 就會一直執行到程式結束。 這顯然不是我們希望得到的效果。 我們只是希望推出函式內部的除錯。 我們的解決辦法就是使用命令r, 然後ENTER,就退出函式內部的除錯。





相關文章