使用Python中PDB模塊中的命令來調(diào)試Python代碼的教程
你有多少次陷入不得不更改別人代碼的境地?如果你是一個開發(fā)團隊的一員,那么你遇到上述境地的次數(shù)比你想要的還要多。然而,Python中有一個整潔的調(diào)試特性(像其他大多數(shù)語言一樣),在這種情況下使用非常方便。本文是一篇快速教程,希望它能讓你的編碼生活更加容易。
1. 一個混亂的程序
出于本教程的目的,讓我們研究一下下面的簡單程序。
這個程序接收兩個命令行參數(shù),然后執(zhí)行加法和減法操作。
(假設(shè)用戶輸入的是有效值,因此代碼中我們沒有進行錯誤處理。)
import sys def add(num1=0, num2=0): return int(num1) + int(num2) def sub(num1=0, num2=0): return int(num1) - int(num2) def main(): #Assuming our inputs are valid numbers print sys.argv addition = add(sys.argv[1], sys.argv[2]) print addition subtraction = sub(sys.argv[1], sys.argv[2]) print subtraction if __name__ == '__main__': main()
2. PDB
Python提供了一個有用的模塊PDB,它實際上是一個交互式源代碼調(diào)試器。
你需要下面的兩行代碼來使用此模塊。
import pdb pdb.set_trace()
看一下我們修改過的程序,里面包含了一些斷點。
import pdb import sys def add(num1=0, num2=0): return int(num1) + int(num2) def sub(num1=0, num2=0): return int(num1) - int(num2) def main(): #Assuming our inputs are valid numbers print sys.argv pdb.set_trace() # <-- Break point added here addition = add(sys.argv[1], sys.argv[2]) print addition subtraction = sub(sys.argv[1], sys.argv[2]) print subtraction if __name__ == '__main__': main()
3. 程序執(zhí)行觸發(fā)調(diào)試器
一旦你設(shè)置好斷點以后,你就可以像平時一樣執(zhí)行程序。
python debugger.py 1 2
程序?qū)谟龅降牡谝粋€斷點處停止執(zhí)行。
['debugger.py'] > /Users/someuser/debugger.py(15)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb)
我們在第14行設(shè)置了一個斷點,所以我們能看到將要執(zhí)行的下一行是第15行??梢钥吹剑趫?zhí)行到第15行之前程序已經(jīng)停止。
在這里我們有幾個選項,讓我們在下面步驟中看看一些調(diào)試指令。
4. 下一行->n
在你的調(diào)試器提示中,輸入n運行到下一行。
> /Users/someuser/debugger.py(14)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb) n > /Users/someuser/debugger.py(15)main() -> print addition
這會執(zhí)行當(dāng)前行代碼,并準(zhǔn)備執(zhí)行下一行。
我們可以使用n來逐行執(zhí)行整個程序,但這其實沒有什么用處。
可能你已經(jīng)看到,PDB實際上并沒有進入我們的add函數(shù)中。下面,就讓我們看看其他幾個令調(diào)試更加有趣的選項。
注意:
一個更酷的特性是你可以單擊回車鍵來執(zhí)行以前的命令(在本例中只要指令n)。
5. 打印->p
下面,我們再次開始調(diào)試程序。(你可以通過單擊c使PDB跳到末尾或者直到下一個斷點,因為程序中我們并沒有其他的斷點了,所有程序?qū)?zhí)行完成。)
['debugger.py', '1', '2'] > /Users/someuser/debugger.py(14)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb)
現(xiàn)在,如果我們想知道sys.argv中包含什么內(nèi)容,我們可以輸入以下內(nèi)容:
-> addition = add(sys.argv[1], sys.argv[2]) (Pdb) p sys.argv ['debugger.py', '1', '2'] (Pdb) p sys.argv[1] '1' (Pdb)
使用這種方法可以相當(dāng)方便地查看變量中實際存儲著什么值。
現(xiàn)在我們將進入加法函數(shù)內(nèi)部。
6. 單步->s
我們可以使用“s”進入加法函數(shù)內(nèi)部。
(Pdb) s --Call-- > /Users/someuser/debugger.py(4)add() -> def add(num1=0, num2=0): (Pdb) n > /Users/someuser/debugger.py(5)add() -> return int(num1) + int(num2) (Pdb)
這將把我們帶入加法函數(shù)的內(nèi)部,現(xiàn)在我們可以在加法函數(shù)內(nèi)部使用n、p和其他的操作指令。
此時單擊“r”將會把我們帶到前面進入函數(shù)的返回語句。
如果你想快速跳轉(zhuǎn)到一個函數(shù)的結(jié)尾處,那么這個指令將很有用。
7. 動態(tài)添加斷點- > b
前面,在程序運行之前,我們使用pdb.set_trace()設(shè)置了一個斷點。
不過,經(jīng)常在調(diào)試會話已經(jīng)開始之后,我們想要在程序中特定的地方添加斷點。
這里我們就可以使用選項“b”來實現(xiàn)這種目的。
我們重新開始執(zhí)行程序。
['debugger.py', '1', '2'] > /Users/someuser/debugger.py(15)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb)
此時我在第18行設(shè)置一個斷點。
-> addition = add(sys.argv[1], sys.argv[2]) (Pdb) b 18 Breakpoint 1 at /Users/someuser/debugger.py:18 (Pdb) c We are in add-- 3 > /Users/someuser/debugger.py(18)main() -> print subtraction (Pdb) p subtraction -1 (Pdb)
從上面我們可以看到,PDB跳到了第18行并等待下一個指令。
同時,PDB還為該斷點分配了一個號碼(在本例中是1)。為了以后的執(zhí)行,我們可以通過開啟或禁用斷點號碼來啟用或停用對應(yīng)的斷點。
8. 列表->l
有時在調(diào)試的時候,你可能會忘記此時你處在代碼的什么地方。在這種情況下,使用“l(fā)”將會打印出一個友好的總結(jié),它能夠顯示出此刻你在代碼中的位置。
['debugger.py', '1', '2'] > /Users/someuser/debugger.py(15)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb) l 10 11 def main(): 12 #Assuming our inputs are valid numbers 13 print sys.argv 14 pdb.set_trace() # <-- Break point added here 15 -> addition = add(sys.argv[1], sys.argv[2]) 16 print addition 17 subtraction = sub(sys.argv[1], sys.argv[2]) 18 print subtraction
9. 動態(tài)分配變量
在調(diào)試會話期間,你可以分配變量來幫助你進行調(diào)試,知道這些對你來說也是有幫助的。例如:
['debugger.py', '1', '2'] > /Users/someuser/debugger.py(15)main() -> addition = add(sys.argv[1], sys.argv[2]) (Pdb) n We are in add-- > /Users/someuser/debugger.py(16)main() -> print addition (Pdb) p addition 3 #<--- addition here is 3 (Pdb) addition = 'this is now string' #<--- We changed the value of additon (Pdb) n this is now string #<--- Now when we print it we actually gets it as a string. that we just set above. > /Users/someuser/debugger.py(17)main() -> subtraction = sub(sys.argv[1], sys.argv[2])
注意:
如果你想設(shè)置一些如n(即PDB指令)這樣的變量,你應(yīng)該使用這種指令:
(Pdb) !n=5 (Pdb) p n 5
10. 結(jié)束->q
最后,在代碼的任何地方如果你想結(jié)束調(diào)試,可以使用“q”,那么正在執(zhí)行的程序?qū)K止。
11. 擴展閱讀
本文只涉及到了PDB的表面用法,其實使用PDB你還可以做到更多(PDB 文檔)。
使用IPython的人可以在ipdb中找到一個更好的調(diào)試器,它提供了tab補充、語法高亮和其他一些很酷的特性。
相關(guān)文章
Django rest framework實現(xiàn)分頁的示例
這篇文章主要介紹了Django rest framework實現(xiàn)分頁的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05python數(shù)據(jù)可視化Pyecharts庫sankey修改桑葚圖顏色
這篇文章主要介紹了python數(shù)據(jù)化Pyecharts庫sankey修改桑葚圖顏色,文中有之前繪制桑葚圖教程鏈接,本文就來修改一下桑葚圖的顏色,有需要的朋友歡迎參閱借鑒2021-09-09詳解Python中__new__和__init__的區(qū)別與聯(lián)系
在Python中,每個對象都有兩個特殊的方法:__new__和__init__,本文將詳細介紹這兩個方法的不同之處以及它們之間的聯(lián)系,具有一定的參考價值,感興趣的可以了解一下2023-12-12