程序一次写完并正常运行的情况很难发生,总会用各种各样的bug去修正,因此需要一些调试手段来修复BUG。
1 使用print()函数将可能有问题的变量打印出来看看
>>> def foo(s):
n = int(s)
print('>>> n = %d' % n)
return 10 / n
>>> def main():
foo('0')
>>> main()
>>> n = 0
Traceback (most recent call last):
File "<pyshell#84>", line 1, in <module>
main()
File "<pyshell#83>", line 2, in main
foo('0')
File "<pyshell#80>", line 4, in foo
return 10 / n
ZeroDivisionError: division by zero
但使用print()坏处之一就是后期还需要删掉print。
2 断言(assert)
凡是可以用print()来辅助查看的地方,均可以使用assert(断言)来替代。
>>> def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
>>> def main():
foo('0')
>>> main()
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
main()
File "<pyshell#6>", line 2, in main
foo('0')
File "<pyshell#3>", line 3, in foo
assert n != 0, 'n is zero!'
AssertionError: n is zero!
assert判断n!=0一定为True,否则后面的代码运行肯定会出错,若assert失败,会抛出AssertionError。
在python解释器中可利用-O(大写字母O)参数来关闭assert。
3 logging
将print()换为logging,和assert相比,logging可以输出到文件,且logging记录分五个级别,从低到高为debug, info, warn, error, crtical,例如将记录设置为info,debug级别信息就无法记录。
import logging
logging.basicConfig(level=logging.INFO)
s = '0'
n = int(s)
logging.debug('n = %d' % n)
logging.info('n = %d' % n)
logging.warning('n = %d' % n)
logging.error('n = %d' % n)
logging.critical('n = %d' % n)
print(10 / n)
INFO:root:n = 0
WARNING:root:n = 0
ERROR:root:n = 0
CRITICAL:root:n = 0
Traceback (most recent call last):
File "E:/untitled/err_logging.py", line 11, in <module>
print(10 / n)
ZeroDivisionError: division by zero
4 pdb.set_trace()
与pdb相比,不需要单步执行,只需要import pdb,在可能出错的地方放一个pdb.set_trace(),可以设置一个断点,运行代码,程序会在pdb.set_trace()暂停并进入pdb调试环境,可以使用命令p产看变量,命令c继续运行,例如:
# err1.py
import pdb
s = '0'
n = int(s)
pdb.set_trace()
print(10 / n)
-> print(10 / n)
(Pdb) p n
0
(Pdb) c
Traceback (most recent call last):
File "D:/Users/Administrator/AppData/Local/Programs/Python/Python36-32/MyPythonScripts/err1.py", line 7, in <module>
print(10 / n)
ZeroDivisionError: division by zero