標籤:des http io ar os 使用 sp for strong
Debug功能對於developer是非常重要的,python提供了相應的模組pdb讓你可以在用文字編輯器寫指令碼的情況下進行debug. pdb是python debugger的簡稱。
常用的一些命令如下:
命令 |
用途 |
break 或 b |
設定斷點 |
continue 或 c |
繼續執行程式 |
list 或 l |
查看當前行的程式碼片段 |
step 或 s |
進入函數 |
return 或 r |
執行代碼直到從當前函數返回 |
exit 或 q |
中止並退出 |
next 或 n |
執行下一行 |
pp |
列印變數的值 |
help |
協助 |
開始介紹如何使用pdb。
使用的測試代碼1: epdb1.py
import pdb
a = "aaa"
pdb.set_trace()
b = "bbb"
c = "ccc"
final = a + b + c
print final
關於set_trace()
pdb.set_trace()¶
-
Enter the debugger at the calling stack frame. This is useful to hard-code abreakpoint at a given point in a program, even if the code is not otherwisebeing debugged (e.g. when an assertion fails).
1 開始調試:
[[email protected] ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb)
> /root/epdb1.py(6)?()
-> final = a + b + c
(Pdb) list
1 import pdb
2 a = "aaa"
3 pdb.set_trace()
4 b = "bbb"
5 c = "ccc"
6 -> final = a + b + c
7 print final
[EOF]
(Pdb)
[EOF]
(Pdb) n
> /root/epdb1.py(7)?()
-> print final
(Pdb)
- 使用n+enter表示執行當前的statement,在第一次按下了n+enter之後可以直接按enter表示重複執行上一條debug命令。
If you press ENTER without entering anything, pdb will re-execute the last command that you gave it.
- quit或者q可以退出當前的debug,但是quit會以一種非常粗魯的方式退出程式,直接crash
[[email protected] ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb) q
Traceback (most recent call last):
File "epdb1.py", line 5, in ?
c = "ccc"
File "epdb1.py", line 5, in ?
c = "ccc"
File "/usr/lib64/python2.4/bdb.py", line 48, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/lib64/python2.4/bdb.py", line 67, in dispatch_line
if self.quitting: raise BdbQuit
bdb.BdbQuit
- 在使用過程中列印變數的值,可以直接使用p加上變數名,但是需要注意的是列印僅僅在當前的statement已經被執行了之後才能看到具體的值,否則會報 NameError: <exceptions.NameError 。。> 錯誤。
[[email protected] ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb) p b
‘bbb‘
(Pdb)
‘bbb‘
(Pdb) n
> /root/epdb1.py(6)?()
-> final = a + b + c
(Pdb) p c
‘ccc‘
(Pdb) p final
*** NameError: <exceptions.NameError instance at 0x1551b710>
(Pdb) n
> /root/epdb1.py(7)?()
-> print final
(Pdb) p final
‘aaabbbccc‘
(Pdb)
使用c可以停止當前的debug使得程式繼續執行。如果在下面的程式中繼續有set_statement()的申明,則又會重新進入到debug的狀態。
[[email protected] ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb) c
aaabbbccc
可以在代碼print final之前再加上set_trace()驗證。
- 如果代碼過程,在debug的時候不一定能記住當前的代碼快,則可以通過使用list或者l命令在顯示。list會用箭頭->指向當前debug的語句
[[email protected]c-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) list
1 import pdb
2 a = "aaa"
3 pdb.set_trace()
4 -> b = "bbb"
5 c = "ccc"
6 final = a + b + c
7 pdb.set_trace()
8 print final
[EOF]
(Pdb) c
> /root/epdb1.py(8)?()
-> print final
(Pdb) list
3 pdb.set_trace()
4 b = "bbb"
5 c = "ccc"
6 final = a + b + c
7 pdb.set_trace()
8 -> print final
[EOF]
(Pdb)
對於使用函數的情況下進行debug:
epdb2.py --import pdbdef 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
如果直接使用n進行debug則到final=combine這句的時候會將其當做普通的指派陳述式處理,進入到print final。如果想要對函數進行debug如何處理?可以直接使用s進入函數塊。
[[email protected] ~]# python epdb2.py
> /root/epdb2.py(10)?()
-> b = "bbb"
(Pdb) n
> /root/epdb2.py(11)?()
-> c = "ccc"
(Pdb) n
> /root/epdb2.py(12)?()
-> final = combine(a,b)
(Pdb) s
--Call--
> /root/epdb2.py(3)combine()
-> def combine(s1,s2): # define subroutine combine, which...
(Pdb) n
> /root/epdb2.py(4)combine()
-> s3 = s1 + s2 + s1 # sandwiches s2 between copies of s1, ...
(Pdb) list
1 import pdb
2
3 def combine(s1,s2): # define subroutine combine, which...
4 -> s3 = s1 + s2 + s1 # sandwiches s2 between copies of s1, ...
5 s3 = ‘"‘ + s3 +‘"‘ # encloses it in double quotes,...
6 return s3 # and returns it.
7
8 a = "aaa"
9 pdb.set_trace()
10 b = "bbb"
11 c = "ccc"
(Pdb) n
> /root/epdb2.py(5)combine()
-> s3 = ‘"‘ + s3 +‘"‘ # encloses it in double quotes,...
(Pdb) n
> /root/epdb2.py(6)combine()
-> return s3 # and returns it.
(Pdb) n
--Return--
> /root/epdb2.py(6)combine()->‘"aaabbbaaa"‘
-> return s3 # and returns it.
(Pdb) n
> /root/epdb2.py(13)?()
-> print final
(Pdb)
如果不想在函數裡單步調試可以在斷點出直接按r退出到調用的地方。
在調試的時候動態改變值 。注意下面有個錯誤,原因是b已經被賦值了,如果想重新改變b的賦值,則應該使用!b
[[email protected] ~]# python epdb2.py
> /root/epdb2.py(10)?()
-> b = "bbb"
(Pdb) var = "1234"
(Pdb) b = "avfe"
*** The specified object ‘= "avfe"‘ is not a function
or was not found along sys.path.
(Pdb) !b="afdfd"
(Pdb)
再貼一篇好文章:http://onlamp.com/pub/a/python/2005/09/01/debugger.html?page=1
Debugger Module Contents
The pdb
module contains the debugger. pdb
containsone class, Pdb
, which inherits from bdb.Bdb
. Thedebugger documentation mentions six functions, which create an interactivedebugging session:
pdb.run(statement[, globals[, locals]]) pdb.runeval(expression[, globals[, locals]]) pdb.runcall(function[, argument, ...]) pdb.set_trace() pdb.post_mortem(traceback) pdb.pm()
All six functions provide a slightly different mechanism for dropping a userinto the debugger.
pdb.run(statement[, globals[, locals]])
pdb.run()
executes the string statement
under thedebugger‘s control. Global and local dictionaries are optional parameters:
#!/usr/bin/env python import pdb def test_debugger(some_int): print "start some_int>>", some_int return_int = 10 / some_int print "end some_int>>", some_int return return_int if __name__ == "__main__": pdb.run("test_debugger(0)")
pdb.runeval(expression[,globals[, locals]])
pdb.runeval()
is identical to pdb.run()
, exceptthat pdb.runeval()
returns the value of the evaluated stringexpression
:
#!/usr/bin/env python import pdb def test_debugger(some_int): print "start some_int>>", some_int return_int = 10 / some_int print "end some_int>>", some_int return return_int if __name__ == "__main__": pdb.runeval("test_debugger(0)")
pdb.runcall(function[,argument, ...])
pdb.runcall()
calls the specified function
andpasses any specified arguments to it:
#!/usr/bin/env python import pdb def test_debugger(some_int): print "start some_int>>", some_int return_int = 10 / some_int print "end some_int>>", some_int return return_int if __name__ == "__main__": pdb.runcall(test_debugger, 0)
pdb.set_trace()
pdb.set_trace()
drops the code into the debugger when executionhits it:
#!/usr/bin/env python import pdb def test_debugger(some_int): pdb.set_trace() print "start some_int>>", some_int return_int = 10 / some_int print "end some_int>>", some_int return return_int if __name__ == "__main__": test_debugger(0)
pdb.post_mortem(traceback)
pdb.post_mortem()
performs postmortem debugging of thespecified traceback
:
#!/usr/bin/env python import pdb def test_debugger(some_int): print "start some_int>>", some_int return_int = 10 / some_int print "end some_int>>", some_int return return_int if __name__ == "__main__": try: test_debugger(0) except: import sys tb = sys.exc_info()[2] pdb.post_mortem(tb)
pdb.pm()
pdb.pm()
performs postmortem debugging of the tracebackcontained in sys.last_traceback
:
#!/usr/bin/env python import pdb import sys def test_debugger(some_int): print "start some_int>>", some_int return_int = 10 / some_int print "end some_int>>", some_int return return_int def do_debugger(type, value, tb): pdb.pm() if __name__ == "__main__": sys.excepthook = do_debugger test_debugger(0)
【Python】debug工具-pdb(轉)