python之错误调试
程序员文章站
2024-01-22 12:34:04
无论谁写的程序,必定会存在bug,解决bug需要我们去调试程序。于是乎,在Python中,就会好几种调试手段,如print、assert、logging、pdb、pdb.set_trace() 一、使用print()函数直接打印 我们可以在认为可能出错的地方打印变量,但这有很大的弊端,因为打印的代码 ......
无论谁写的程序,必定会存在bug,解决bug需要我们去调试程序。于是乎,在python中,就会好几种调试手段,如print、assert、logging、pdb、pdb.set_trace()
一、使用print()函数直接打印
>>> def foo(s): ... n = int(s) ... print(n) ... return 10 / n ... >>> def main(): ... foo('0') ... >>> main() 0 traceback (most recent call last): file "<stdin>", line 1, in <module> file "<stdin>", line 2, in main file "<stdin>", line 4, in foo zerodivisionerror: division by zero
我们可以在认为可能出错的地方打印变量,但这有很大的弊端,因为打印的代码没有实际功能,都是垃圾信息。而且print最后还得删除,所以第二种方法是用assert替代print
二、使用断言assert
>>> def foo(s): ... n = int(s) ... assert n != 0,'n的值是0!' ... return 10 / n ... >>> def main(): ... foo('0') ... >>> main() traceback (most recent call last): file "<stdin>", line 1, in <module> file "<stdin>", line 2, in main file "<stdin>", line 3, in foo assertionerror: n的值是0!
assert的意思,当后面的表达式为false时,就会抛出assertionerror,如果为true,什么都不做,直接到下一行。assert有一大特性:在启动python解释器的时候可以使用-o参数来关闭assert(大写的o)
ps e:\python3.6.3\workspace> python -o err_assert.py traceback (most recent call last): file "err_assert.py", line 9, in <module> main() file "err_assert.py", line 7, in main foo('0') file "err_assert.py", line 4, in foo return 10 / n zerodivisionerror: division by zer
三、使用logging
import logging logging.basicconfig(level=logging.info) s = '0' n = int(s) logging.info('n=%d' % n) print(10/n) #执行结果 ps e:\python3.6.3\workspace> python err_logginginfo.py info:root:n=0 traceback (most recent call last): file "err_logginginfo.py", line 6, in <module> print(10/n) zerodivisionerror: division by zero
使用logging不会抛出错误,直接输出到文件中。logging可以允许你指定记录信息的级别,级别由低到高分别是debug、info、warning、error、critical等级别,当定义高级别的时候,低级别的信息不会输出,这是把日志信息输出到控制台console,我们还可以通过设置把日志输出到文件中
四、使用python的调试器pdb
可以让程序以单步方式执行,方便我们随时查看运行状态
新建程序err_pdb.py
s = '0' n = int(s) print(10 / n)
然后以pdb模式启动
ps e:\python3.6.3\workspace> python -m pdb err_pdb.py > e:\python3.6.3\workspace\err_pdb.py(1)<module>() -> s = '0' (pdb) l 1 -> s = '0' 2 n = int(s) 3 print(10 / n) [eof] (pdb) n > e:\python3.6.3\workspace\err_pdb.py(2)<module>() -> n = int(s) (pdb) p s '0' (pdb) p n *** nameerror: name 'n' is not defined (pdb) n > e:\python3.6.3\workspace\err_pdb.py(3)<module>() -> print(10 / n) (pdb) p n 0 (pdb) p s '0' (pdb) n zerodivisionerror: division by zero > e:\python3.6.3\workspace\err_pdb.py(3)<module>() -> print(10 / n) (pdb) n --return-- > e:\python3.6.3\workspace\err_pdb.py(3)<module>()->none -> print(10 / n) (pdb) n zerodivisionerror: division by zero > <string>(1)<module>()->none (pdb) n --return-- > <string>(1)<module>()->none (pdb) n traceback (most recent call last): file "e:\python3.6.3\lib\pdb.py", line 1667, in main pdb._runscript(mainpyfile) file "e:\python3.6.3\lib\pdb.py", line 1548, in _runscript self.run(statement) file "e:\python3.6.3\lib\bdb.py", line 431, in run exec(cmd, globals, locals) file "<string>", line 1, in <module> file "e:\python3.6.3\workspace\err_pdb.py", line 3, in <module> print(10 / n) zerodivisionerror: division by zero uncaught exception. entering post mortem debugging running 'cont' or 'step' will restart the program > e:\python3.6.3\workspace\err_pdb.py(3)<module>()->none -> print(10 / n) (pdb) q post mortem debugger finished. the err_pdb.py will be restarted > e:\python3.6.3\workspace\err_pdb.py(1)<module>() -> s = '0' (pdb) n > e:\python3.6.3\workspace\err_pdb.py(2)<module>() -> n = int(s) (pdb) q ps e:\python3.6.3\workspace>
小写字母l,可以列出所有要执行的代码; n 命令表示单步执行代码; p 后面加上变量名,可以随时查看变量的值; 在pdb模式中,对于还没有单步执行到的代码,相关的变量的变更是无效的; q 命令退出当前调试,进入重新从头开始调试,再次输入q,就会推出调试程序。 这种方式的调试,有一个弊端,就是只能一步一步的执行下去,如果程序有很多行,岂不是累死。
五、使用pdb.set_trace()
#err_pdb.py import pdb s = '0' n = int(s) pdb.set_trace() #程序运行到这里会自动停止,等待命令 print(10 / n)
我们可以使用l、c、n、p、q等命令来控制和查看程序
ps e:\python3.6.3\workspace> python err_pdb.py > e:\python3.6.3\workspace\err_pdb.py(7)<module>() -> print(10 / n) (pdb) p s '0' (pdb) l 2 import pdb 3 4 s = '0' 5 n = int(s) 6 pdb.set_trace() #程序运行到这里会自动停止,等待命令 7 -> print(10 / n) [eof] (pdb) n zerodivisionerror: division by zero > e:\python3.6.3\workspace\err_pdb.py(7)<module>() -> print(10 / n) (pdb) c traceback (most recent call last): file "err_pdb.py", line 7, in <module> print(10 / n) zerodivisionerror: division by zero
推荐阅读