Python调试方法简介
纸上得来终觉浅,绝知此事要躬行。
日常我们写代码时,很容易导致程序出错,而且有些原因很难被我们发现,所以如何调试检查出问题所在是一个关键的技巧。
常见调试方法
- pdb
- ipython
- ide
调试经验总结
- 调试只是开发时的使用的方法,线上环境应该记录业务日志,也应该是用sentry搜集错误日志,通过这些日志去回溯问题,不应该等出了问题进行线上调试。
参考链接
1. 使用 print 调试
- 通过在指定的区域打印对应输出来定位问题
def div(a, b): return a / b def main(a=1, b=0): print(a, b) return div(a, b) if __name__ == '__main__': main()
2. 使用 pdb 调试
- 对指定位置调试
[[email protected] ~]$ python test.py > /Users/escape/Escape/MorePractise/test.py(6)div() -> return a / b (Pdb) list 1 import pdb 2 3 4 def div(a, b): 5 pdb.set_trace() 6 -> return a / b 7 8 def main(a=1, b=0): 9 return div(a, b) 10 11 if __name__ == '__main__': (Pdb) p a 1 (Pdb) p b 0 (Pdb) c Traceback (most recent call last): File "test.py", line 12, in <module> main() File "test.py", line 9, in main return div(a, b) File "test.py", line 6, in div return a / b ZeroDivisionError: division by zero
- 也可以单步调试
[[email protected] ~]$ python -m pdb test.py > /Users/escape/Escape/MorePractise/test.py(1)<module>() -> import pdb (Pdb) help Documented commands (type help <topic>): ======================================== EOF c d h list q rv undisplay a cl debug help ll quit s unt alias clear disable ignore longlist r source until args commands display interact n restart step up b condition down j next return tbreak w break cont enable jump p retval u whatis bt continue exit l pp run unalias where Miscellaneous help topics: ========================== exec pdb (Pdb) n > /Users/escape/Escape/MorePractise/test.py(4)<module>() -> def div(a, b): (Pdb) n > /Users/escape/Escape/MorePractise/test.py(7)<module>() -> def main(a=1, b=0): (Pdb) list 2 3 4 def div(a, b): 5 return a / b 6 7 -> def main(a=1, b=0): 8 print(a, b) 9 return div(a, b) 10 11 if __name__ == '__main__': 12 main() (Pdb) n > /Users/escape/Escape/MorePractise/test.py(11)<module>() -> if __name__ == '__main__': (Pdb) j 5 > /Users/escape/Escape/MorePractise/test.py(5)<module>() -> return a / b (Pdb) list (Pdb) list 2 3 4 def div(a, b): 5 return a / b 6 7 -> def main(a=1, b=0): 8 print(a, b) 9 return div(a, b) 10 11 if __name__ == '__main__': 12 main() (Pdb) c 1 0 Traceback (most recent call last): File "/Users/escape/.pyenv/versions/3.6.4/lib/python3.6/pdb.py", line 1667, in main pdb._runscript(mainpyfile) File "/Users/escape/.pyenv/versions/3.6.4/lib/python3.6/pdb.py", line 1548, in _runscript self.run(statement) File "/Users/escape/.pyenv/versions/3.6.4/lib/python3.6/bdb.py", line 431, in run exec(cmd, globals, locals) File "<string>", line 1, in <module> File "/Users/escape/Escape/MorePractise/test.py", line 7, in <module> def main(a=1, b=0): File "/Users/escape/Escape/MorePractise/test.py", line 9, in main return div(a, b) File "/Users/escape/Escape/MorePractise/test.py", line 5, in div return a / b ZeroDivisionError: division by zero Uncaught exception. Entering post mortem debugging Running 'cont' or 'step' will restart the program > /Users/escape/Escape/MorePractise/test.py(5)div() -> return a / b (Pdb) p a 1 (Pdb) p b 0 (Pdb) a a = 1 b = 0 (Pdb) q Post mortem debugger finished. The test.py will be restarted > /Users/escape/Escape/MorePractise/test.py(1)<module>() -> import pdb (Pdb) q
3. 使用 ipython 调试
- 使用ipython自带的ipdb进行代码的调试
[[email protected] ~]$ ipython -i test.py --pdb --no-banner 1 0 --------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) ~/Escape/MorePractise/test.py in <module>() 10 11 if __name__ == '__main__': ---> 12 main() ~/Escape/MorePractise/test.py in main(a, b) 7 def main(a=1, b=0): 8 print(a, b) ----> 9 return div(a, b) 10 11 if __name__ == '__main__': ~/Escape/MorePractise/test.py in div(a, b) 3 4 def div(a, b): ----> 5 return a / b 6 7 def main(a=1, b=0): ZeroDivisionError: division by zero > /Users/escape/Escape/MorePractise/test.py(5)div() 3 4 def div(a, b): ----> 5 return a / b 6 7 def main(a=1, b=0): ipdb> p b 0 ipdb> p a 1 ipdb> q