Python调试方法简介


纸上得来终觉浅,绝知此事要躬行。

Python调试方法简介


日常我们写代码时,很容易导致程序出错,而且有些原因很难被我们发现,所以如何调试检查出问题所在是一个关键的技巧。

常见调试方法

  • print
  • 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 调试

  • 对指定位置调试
[escape@localhost ~]$ 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
  • 也可以单步调试
[escape@localhost ~]$ 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进行代码的调试
[escape@localhost ~]$ 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

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录