在Python中,語法錯誤可以被Python解釋器發現,但邏輯上錯誤或變量使用錯誤卻不容易發現,如果結果沒有符合預期,則需要調試,一個很好的調試工具:Python自帶的pdb模塊。pdb是Python自帶的調試模塊。使用pdb模塊可以為腳本設置斷點、單步執行、查看變量值等。
pdb可以用命令行參數的方式啟動,也可以使用import 將其導入后再使用。
>>> dir(pdb)?
['Pdb', 'Repr', 'Restart', 'TESTCMD',.....,'re', 'run', 'runcall', 'runctx', 'runeval', 'set_trace', 'sys', 'test', 'traceback']?
常見的pdb函數有以下幾個:
【pdb.run()函數】
>>> 該函數主要用于調試語句塊
>>> 基本用法如下
>>> help(pdb.run)?
Help on function run in module pdb:?
?
run(statement, globals=None, locals=None)?
>>>參數含義
statement: 要調試的語句塊,以字符串的形式表示
globals:?? 可選參數,設置statement運行的全局環境變量
locals:???? 可選參數,設置statement運行的局部環境變量
>>>簡單示例
>>> import pdb??????????????? # 導入調試模塊?
>>> pdb.run('''''?????????????? # 調用run()函數執行一個for循環
for i in range(3):
??? i *= 3
??? print(i)
??? ''')?
>
(Pdb) n?????????????????????? # (Pdb)為調試命令提示符,表示可輸入調試命令?
>
(Pdb) n?????????????????????? # n(next)表示執行下一行?
>
(Pdb) print(i)??????????????? # 打印變量i的值?
0?
(Pdb) continue??????????????? # 繼續運行程序?
0?
3?
6?
【pdb.runeval()函數】
>>>該函數主要用于調試表達式
>>>基本用法如下
>>> help(pdb.runeval)?
Help on function runeval in module pdb:?
?
runeval(expression, globals=None, locals=None)?
>>> 參數含義
expression: 要調試的,
globals:?? 可選參數,設置statement運行的全局環境變量
locals:???? 可選參數,設置statement運行的局部環境變量
>>> 簡單示例
>>> import pdb????????????????? # 導入pdb模塊?
>>> lst = [1, 2, 3]???????????? # 定義一個列表?
>>> pdb.runeval('lst[1]')?????? # 調用runaval()函數來調試表達式lst[1]?
>
(Pdb) n???????????????????????? # 進入調試狀態,使用n命令,單步執行?
--Return--?
>
(Pdb) n???????????????????????? # 單步執行?
2?????????????????????????????? # 返回表達式的值?
>>> pdb.runeval('3 + 5*6/2')??? # 使用runaval()函數來調試表達式3+5*6/2?
>
(Pdb) n?
--Return--?
>
(Pdb) n???????????????????????? # 使用n命令單步執行?
18????????????????????????????? # 最后得出表達式的值?
【pdb.runcall()函數】
>>>該函數主要用于調試函數
>>>基本用法如下
>>> help(pdb.runcall)?
Help on function runcall in module pdb:?
?
runcall(*args, **kwds)?
>>> 參數含義
function:????????? 函數名
args(kwds):??????? 函數的參數
>>> 簡單示例
>>> import pdb?????????????????????????? # 導入模塊?
>>> def sum(*args):????????????????????? # 定義函數sum,求所有參數之和?
??? res = 0?
??? for arg in args:?
??????? res += arg?
??? return res?
?
>>> pdb.runcall(sum, 1, 2, 3, 4)???????? # 使用runcall調試函數sum?
>
(Pdb) n????????????????????????????????? # 進入調試狀態,單步執行?
>
(Pdb) n????????????????????????????????? # 單步執行?
>
(Pdb) print(res)???????????????????????? # 使用print打印res的值?
0?
(Pdb) continue?????????????????????????? # 繼續執行?
10?
>>> pdb.runcall(sum, 1, 2, 3, 4, 5, 6)?? # 調用runcall調試函數sum,參數不同?
?
>
(Pdb) continue?????????????????????????? # 繼續執行?
21?????????????????????????????????????? # 函數最后返回結果?
【pdb.set_trace()函數】
>>>該函數主要用于腳本中設置硬斷點
>>>基本用法如下
>>> help(pdb.set_trace)?
Help on function set_trace in module pdb:?
?
set_trace()?
>>>簡單示例
# file: test.py?
?
import pdb?
?
pdb.set_trace()?
for i in range(5):?
??? i *= 5?
??? print(i)?
運行腳本后顯示:
> d:\learn\python\test.py(6)
-> for i in range(5):?
(Pdb) list???????????????????? # 使用list列出腳本內容?
? 1???? # file: test.py?
? 2??????
? 3???? import pdb?
? 4??????
? 5???? pdb.set_trace()??????? # 使用set_trace()設置硬斷點?
? 6? ->? for i in range(5):?
? 7???????? i *= 5?
? 8???????? print(i)?
[EOF]????????????????????????? # 列出腳本內容結束?
(Pdb) continue???????????????? # 使用continue繼續執行?
0?
5?
10?
15?
20?
【pdb調試命令】
pdb中的調試命令可以完成單步執行、打印變量值、設置斷點等功能。pdb主要命令如下
------------------------------------------------------------------------------?
# 完整命令??????????????????? 簡寫命令????????????????????? 描述?
------------------------------------------------------------------------------?
# args???????????????????????? a??????????????????????????? 打印當前函數的參數?
# break??????????????????????? b??????????????????????????? 設置斷點?
# clear??????????????????????? cl?????????????????????????? 清除斷點?
# condition??????????????????? 無?????????????????????????? 設置條件斷點?
# continue???????????????????? c??????????????????????????? 繼續運行,直到遇到斷點或者腳本結束?
# disable????????????????????? 無?????????????????????????? 禁用斷點?
# enable?????????????????????? 無?????????????????????????? 啟用斷點?
# help????????????????????????? h?????????????????????????? 查看pdb幫助?
# ignore?????????????????????? 無?????????????????????????? 忽略斷點?
# jump???????????????????????? j??????????????????????????? 跳轉到指定行數運行?
# list???????????????????????? l??????????????????????????? 列出腳本清單?
# next???????????????????????? n??????????????????????????? 執行下條語句,遇到函數不進入其內部?
# print??????????????????????? p??????????????????????????? 打印變量值?
# quit???????????????????????? q??????????????????????????? 退出pdb?
# return?????????????????????? r??????????????????????????? 一致運行到函數返回?
# tbreak?????????????????????? 無?????????????????????????? 設置臨時斷點、斷點只中斷一次?
# step???????????????????????? s??????????????????????????? 執行下一條語句,遇到函數進入其內部?
# where??????????????????????? w??????????????????????????? 查看所在的位置?
# !?????????????????????????? 無?????????????????????????? 在pdb中執行語句?????????????????????
>>>簡單示例
# -*- coding:gbk -*-?
# file: prime.py?
#?
import math?
# isprime函數判斷一個整數是否為素數?
# 如果i能被2到i的平方根內的任意一個數整除,?
# 則i不是素數,返回0,否則i是素數,返回1。?
def isprime(i):?
??? for t in range(2, int(math.sqrt(i)) + 1):?
??????? if i % t == 0:?
??????????? return 0?
?
?
print('100~110之間素數有: ')?
for i in range(100, 110):?
??? if isprime(i):?
??????? print(i)?
先運行下面命令:
d:\Learn\Python>python -m pdb prime.py?
后輸入以下命令:
d:\Learn\Python>python -m pdb prime.py?
> d:\learn\python\prime.py(4)
-> import math?
(Pdb) list?????????????????????????????????????????? # 運行前面命令后停在這里,list默認只列出11行?
? 1???? # -*- coding:gbk -*-?
? 2???? # file: prime.py?
? 3???? #?
? 4? -> import math?
? 5???? # isprime函數判斷一個整數是否為素數?
? 6???? # 如果i能被2到i的平方根內的任意一個數整除,?
? 7???? # 則i不是素數,返回0,否則i是素數,返回1。?
? 8???? def isprime(i):?
? 9???????? for t in range(2, int(math.sqrt(i)) + 1):?
?10???????????? if i % t == 0:?
?11???????????????? return 0?
(Pdb) l 14,17??????????????????????????????????????? # 使用list命令,列出14行,到17行?
?14???? print('100~110之間素數有: ')?
?15???? for i in range(100, 110):?
?16???????? if isprime(i):?
?17???????????? print(i)?
(Pdb) b 14?????????????????????????????????????????? # 使用break命令設置斷點?
Breakpoint 1 at d:\learn\python\prime.py:14????????? # 返回斷點編號: 1?
(Pdb) b isprime????????????????????????????????????? # 在函數isprime設置斷點?
Breakpoint 2 at d:\learn\python\prime.py:8?????????? # 返回斷點編號: 2?
(Pdb) c????????????????????????????????????????????? # 使用c命令運行運行腳本?
> d:\learn\python\prime.py(14)
-> print('100~110之間素數有: ')?
(Pdb) c????????????????????????????????????????????? # 使用c命令繼續運行腳本?
100~110之間素數有:?????????????????????????????????? # 第14行腳本輸出?
> d:\learn\python\prime.py(9)isprime()?????????????? # 停在斷點2,即isprime函數處?
-> for t in range(2, int(math.sqrt(i)) + 1):?
(Pdb) b 15?????????????????????????????????????????? # 在第15行處設置斷點?
Breakpoint 3 at d:\learn\python\prime.py:15?
(Pdb) disable 2????????????????????????????????????? # 禁用斷點2,即isprime函數處的斷點?
(Pdb) c????????????????????????????????????????????? # 使用c命令繼續運行腳本?
> d:\learn\python\prime.py(15)
-> for i in range(100, 110):?
(Pdb) print(i)?????????????????????????????????????? # 使用print打印變量i的值?
100?
(Pdb) c????????????????????????????????????????????? # 繼續運行腳本?
> d:\learn\python\prime.py(15)
-> for i in range(100, 110):?
(Pdb) p i??????????????????????????????????????????? # 打印i的值?
101?
(Pdb) enable 2?????????????????????????????????????? # 恢復斷點2,即isprime函數處的斷點?
(Pdb) c????????????????????????????????????????????? # 繼續運行腳本?
> d:\learn\python\prime.py(9)isprime()????????????????
-> for t in range(2, int(math.sqrt(i)) + 1):?
(Pdb) n????????????????????????????????????????????? # 單步執行下一條語句???????????????????????????????????????????
> d:\learn\python\prime.py(10)isprime()?
-> if i % t == 0:?
(Pdb) print(t)?????????????????????????????????????? # 使用print打印變量t的值?
2?
(Pdb) cl???????????????????????????????????????????? # 清楚所有斷點,輸入y確認?
Clear all breaks? y?
(Pdb) c????????????????????????????????????????????? # 繼續運行腳本?
103?
105?
107?
109?
(Pdb) q????????????????????????????????????????????? # 使用quit(q)退出pdb調試?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
