對于開發(fā)人員來說,DEBUG是一項必不可少的能力廊驼,在很多開發(fā)工作中是繞不開DEBUG過程的据过。不同的人偏好于不同的DEBU方式,本文就介紹一下Python自帶的一個DEBUG工具包妒挎,對于偏好于使用VIM绳锅、sublime、notepad之類純文本編輯器進(jìn)行開發(fā)的工程人員來說是一個比較基礎(chǔ)且實(shí)用的工具包酝掩。
查看變量值和變量類型是否符合我們預(yù)期是DEBUG過程中一項非常重要的工作或目的鳞芙,很多剛接觸編程語言的人員習(xí)慣于采用print輸出中間變量值或者變量類型,
def test():
x, y = 1, 2
z = x + y
print(z)
?
?
if __name__ == '__main__':
test()
輸出:
>>> 3
用print進(jìn)行debug雖然簡單期虾,但是卻有很多弊端:
- 輸出信息多而雜亂
- 需要在變量處反復(fù)注釋取消注釋原朝,過程繁瑣
log
更近一層的開發(fā)人員會選擇用log日志的方式進(jìn)行debug,通過對輸出日志設(shè)置DEBUG镶苞、INFO喳坠、WARNING、ERROR宾尚、CRITICAL等級別來控制日志的輸出丙笋,當(dāng)輸出級別小于設(shè)置級別時信息不會輸出,當(dāng)級別在設(shè)置級別之上時才會被輸出煌贴,級別大小依次是DEBUG<INFO<WARNING<ERROR<CRITICAL御板,因此,當(dāng)級別設(shè)置為http://logging.INFO時牛郑,DEBUG級別就不會輸出怠肋,WARNING、ERROR淹朋、CRITICAL會輸出笙各,通過這種方式避免不同場景下輸出內(nèi)容雜亂的問題钉答。
import logging
?
logging.basicConfig(level=logging.INFO)
?
?
def test():
x, y = 1, 2
z = x + y
logging.debug(" debug z value : {}".format(z))
logging.warning(" warning z value : {}".format(z))
logging.error(" error z value : {}".format(z))
logging.critical(" critical z value : {}".format(z))
?
?
if __name__ == '__main__':
test()
輸出:
>>> WARNING:root: warning z value : 3
>>> ERROR:root: error z value : 3
>>> CRITICAL:root: critical z value : 3
IDE
目前很多入門或者深入Python的開發(fā)者都選擇使用一些成熟的IDE進(jìn)行開發(fā),例如pycharm杈抢。它自帶debug工具数尿,因此就不需要在代碼中大量的使用print、logging字段惶楼,減少了代碼的繁瑣性右蹦。
例如圖中所示:
通過點(diǎn)擊左側(cè)欄設(shè)置斷點(diǎn)(1)
點(diǎn)擊2所示圖標(biāo)進(jìn)行debug
通過3選擇要執(zhí)行的動作
Step over--下一步
Step into--進(jìn)入函數(shù)
Step out--執(zhí)行剩余部分然后跳出函數(shù)
Run to cursor--執(zhí)行到光標(biāo)處
通過4的variables查看當(dāng)前所有變量
通過5的"+"添加特定要查看的變量
不得不承認(rèn),IDE的debug工具的確很強(qiáng)大歼捐、而且很好用何陆,但是我認(rèn)為這樣有一個弊端,就是過度依賴IDE豹储,如果沒有IDE的話卻不知道從何下手贷盲,然后不得不回到最原始的print、log方式剥扣。
如果有想要學(xué)習(xí)Python或者正在學(xué)習(xí)Python中的小伙伴巩剖,需要學(xué)習(xí)資料的話,可以到我的微信公眾號:Python學(xué)習(xí)知識圈朦乏,后臺回復(fù):“01”球及,即可拿Python學(xué)習(xí)資料
pdb
當(dāng)脫離高效的IDE之后,該怎么進(jìn)行DEBUG呻疹?
很多人喜歡用sublime吃引、vim等純文本編輯器,這些編輯器本身是不具備pycharm這樣高效的debug工具的刽锤,那該怎么樣使得這些文本編輯器也可以用于Python的debug呢镊尺?接下來就介紹一個Python自帶的基礎(chǔ)工具包pdb。
pdb的使用有兩種方式:
- 命令行方式
- 直接導(dǎo)入pdb包
命令行模式直接在命令行下輸入下面命令即可并思,
python -m pdb xxx.py
其中xxx.py指的是需要調(diào)試的Python程序庐氮。
直接導(dǎo)入pdb包的方式如下,
# 導(dǎo)入pdb包
import pdb
?
# 設(shè)置斷點(diǎn)
pdb.set_trace()
?
# 執(zhí)行程序
Python xxx.py
pycharm支持Step over宋彼、Step into弄砍、Step out等快捷方式,pdb是不是僅僅支持set_trace設(shè)置斷點(diǎn)這么弱输涕?當(dāng)然不是音婶!
pdb支持豐富而強(qiáng)大的調(diào)試命令:
命令功能n執(zhí)行下一條語句,相當(dāng)于Step overs相當(dāng)于Step intor執(zhí)行當(dāng)前函數(shù)剩余部分莱坎,相當(dāng)于Step outl列出代碼片段c執(zhí)行到下一個斷點(diǎn)a列出可執(zhí)行的函數(shù)pp輸出變量值q退出debug
對于命令行模式還可以使用如下命令:
命令功能b添加斷點(diǎn):b LineNumber:在指定行添加斷點(diǎn) b FileName:LineNumber:在指定文件的指定行添加斷點(diǎn) b 列出當(dāng)前所有斷點(diǎn)tbreak設(shè)置臨時斷點(diǎn)cl清楚斷點(diǎn)disable停用斷點(diǎn)enable激活斷點(diǎn)
下面就來演示一下:
import pdb
?
?
def add(x, y)
k = 10
z = x + y
for i in range(k):
pdb.set_trace()
z += i
return z
?
def main():
x, y = 1, 2
pdb.set_trace()
z = add(x, y)
print(z)
if __name__ == '__main__':
main()
執(zhí)行程序衣式,到達(dá)第一個斷點(diǎn)處:
python test.py
> d:\pycharmprojects\learning\test.py(15)main()
-> z = add(x, y)
進(jìn)入add函數(shù)(step into):
(Pdb) s
--Call--
> d:\pycharmprojects\learning\test.py(4)add()
-> def add(x, y):
下一行(step over):
(Pdb)
> d:\pycharmprojects\learning\test.py(6)add()
-> z = x + y
執(zhí)行到z=x+y這一行,然后跳過當(dāng)前函數(shù),執(zhí)行剩余部分(step out):
(Pdb) r
--Return--
> d:\pycharmprojects\learning\test.py(10)add()->48
-> return z
輸出變量:
(Pdb) pp z
48
列出當(dāng)前代碼片段:
(Pdb) l
5 k = 10
6 z = x + y
7 for i in range(k):
8 pdb.set_trace()
9 z += i
10 -> return z
11
12 def main():
13 x, y = 1, 2
14 pdb.set_trace()
15 z = add(x, y)
上述就介紹了一種高效的Python調(diào)試工具包碴卧,對于喜歡用文本編輯器進(jìn)行程序開發(fā)的人員來說弱卡,這是非常實(shí)用而且高效的方式,能夠針對性的設(shè)置斷點(diǎn)住册、輸出變量值婶博,不用繁瑣、雜亂的使用print界弧、log方式凡蜻。
當(dāng)然搭综,除了pdb之外還有很多高校的Python調(diào)試工具包垢箕,后續(xù)會單獨(dú)介紹一種更為簡單高效的Python調(diào)試工具。