標籤:python pdb 跟蹤調試
詩歌是一種憂鬱的媒體,而詩人的使命是孤獨的; -- 北島《時間的玫瑰》
學習是一首深邃的民謠,而我們的任務是享受他。 -- 小Q 《20161203》
------------------------------------------------------------------------------------------------
學c++時,老師教我們有gdb調試工具,在工作中會經常用到;
學shell時,經理讓我見到了"-x"跟蹤調試參數,我每天都會用到;
學python後,我就在尋找類似的參數和工具,Google給了我pdb工具;
【簡介調試工具】
pdb
使用如下代碼就相當於添加斷點了:
import pdb
pdb.set_trace() #設定斷點的地方,放置於程式中
ipdb
相對於python,我們更趨向於ipython,有漂亮的顏色,和<tab>補全提示,以及bash混用;
相對於python內建的pdb,ipdb的優勢也正在於此,其實就是對ipython的調用:
import ipdb
ipdb.set_trace()
pudb
是全屏的基於控制台的可視化調試器,有點像c語言中的Turbo C樣式
650) this.width=650;" src="http://s4.51cto.com/wyfs02/M02/8B/05/wKioL1hCYYHRI1AAAACFZHN1Rc0206.png" title="4.png" style="width:700px;height:412px;" alt="wKioL1hCYYHRI1AAAACFZHN1Rc0206.png" width="700" vspace="0" hspace="0" height="412" border="0" />
為了支援pudb,需要在代碼中插入
from pudb import set_trace; set_trace() or import pudb
rpdb
上面的兩種方案要求有終端輸出的情況下可行,有時候我們需要以後台形式執行python,此時是沒有輸出互動的,比如django開發,程式由uwsgi管理執行,標準輸出已重新導向,通常只能通過日誌輸出資訊。這個時候我們就需要一個遠端偵錯工具。
rpdb會開啟一個socket串連,用於遠端偵錯,預設連接埠是4444:
import rpdb
rpdb.set_trace(port=12345)
這樣當程式被hang住之後,會監聽該連接埠,可遠端連線進行調試:
nc 127.0.0.1 12345
ripdb
rpdb只是pdb的遠程版本,而ripdb就是將rpdb和ipdb的功能進行了整合,既有遠端偵錯功能,又有漂亮的代碼顏色:
import ripdb
ripdb.set_trace(port=12345)
如果還需要<Tab>自動補全功能,還需要對終端進行一下設定:
SAVED_STTY=`stty -g`; stty -icanon -opost -echo -echoe -echok -echoctl -echoke; nc 127.0.0.1 12345; stty $SAVED_STTY
【詳解pdb/ipdb】
實驗程式:傳兩個參數,進行加法和減法
import sysdef add(num1=0, num2=0): return int(num1) + int(num2)def sub(num1=0, num2=0): return int(num1) - int(num2)def main(): print sys.argv addition = add(sys.argv[1], sys.argv[2]) print addition subtraction = sub(sys.argv[1], sys.argv[2]) print subtractionif __name__ == ‘__main__‘: main()
1、進入PDB調試,其實就是一個互動式原始碼調試器;修改程式:
import pdb # 添加模組import sysdef add(num1=0, num2=0): return int(num1) + int(num2)def sub(num1=0, num2=0): return int(num1) - int(num2)def main(): 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 subtractionif __name__ == ‘__main__‘: main()
2、程式執行觸發調試器
執行:python 3_pdb.py 1 3 //程式在第一個斷點處停止,如下
650) this.width=650;" src="http://s1.51cto.com/wyfs02/M00/8B/05/wKioL1hCYsmQWwQkAAAUkoyAtno306.png" title="1.png" alt="wKioL1hCYsmQWwQkAAAUkoyAtno306.png" />
此時我們可以看到程式在print sys.argv 處出了一個斷點
並顯示下一步將要執行 addition = add(sys.argv[1], sys.argv[2])
3、下一行 -> n
輸入“n”斷行符號,將會執行addition = add(sys.argv[1], sys.argv[2]),然後列印出下一步操作;
但是會有一個問題,pdb沒有進入到add函數中,下面的s選項可以解決此問題
650) this.width=650;" src="http://s1.51cto.com/wyfs02/M01/8B/08/wKiom1hCYzXSfvTeAAAhQqpbBnA422.png" title="2.png" alt="wKiom1hCYzXSfvTeAAAhQqpbBnA422.png" />
4、列印 -> p
在執行過程中我們想看,某個變數的列印值,除了c可以直接跳到下一個斷點,列印期間所有值
“p”可以列印出某個變數的值,但前提是已經執行過這個變數。如下:
650) this.width=650;" src="http://s5.51cto.com/wyfs02/M00/8B/08/wKiom1hCY2WCTYo_AAAm3dLANS0678.png" title="3.png" alt="wKiom1hCY2WCTYo_AAAm3dLANS0678.png" />
5、單步 -> s
“s”可以進入某個函數內部,然後再函數內使用n/p/b/c等
“r”將返回前面進入函數的返回語句
650) this.width=650;" src="http://s2.51cto.com/wyfs02/M01/8B/05/wKioL1hCY4_R6jV6AAA6AukGwK0704.png" title="4.png" alt="wKioL1hCY4_R6jV6AAA6AukGwK0704.png" />
6、添加動態斷點 -> b
在程式裡,我們設定了一個斷點,但當我們執行很長的代碼時,忘了在指令碼中設定斷點
我們就可以直接用“b”在此環境下設定下一個斷點位置
格式:b 行數
7、列表 -> l
有時再調試時,不知道自己運行到哪,也不知道下面代碼是什麼了,為了不退出去去記某一行是什麼,便可以執行小寫“L”查看後面程式
650) this.width=650;" src="http://s4.51cto.com/wyfs02/M02/8B/08/wKiom1hCY-Din4hJAABvn5xA7H8570.png" title="5.png" style="width:600px;height:395px;" alt="wKiom1hCY-Din4hJAABvn5xA7H8570.png" width="600" vspace="0" hspace="0" height="395" border="0" />
8、動態分配變數
在調試期間,可以分配變數協助進行調試,
(Pdb) !n=5
(Pdb) p n
5
9、結束 -> q/exit
在調試過程,想退出結束調試,可直接運行“q”或“exit”斷行符號即可
--------------------------------------------------------------------------------------------------
PDB文檔:https://docs.python.org/2/library/pdb.html
而ipdb用法和pdb類似,只是更友好,更直觀,如下:
650) this.width=650;" src="http://s5.51cto.com/wyfs02/M01/8B/08/wKiom1hCZDGzIyVIAABRuVQqSMo534.png" title="6.png" alt="wKiom1hCZDGzIyVIAABRuVQqSMo534.png" />
本文出自 “北冰--Q” 部落格,請務必保留此出處http://beibing.blog.51cto.com/10693373/1879356
Python -- pdb調試工具