专栏首页python3python之错误调试

python之错误调试

  无论谁写的程序,必定会存在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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Flask模板

    在模板中{{ variable }}结构表示变量,是一种特殊的占位符,告诉模板引擎这个位置的值,从渲染模板时使用的数据中获取;Jinja2除了能识别基本类型的变...

    py3study
  • python之接口请求

          实际工作中,需要用到python来对服务器进行请求(也是方便进行接口自动化),因为,本文来记录一下python是如何来进行get和post请求的,本...

    py3study
  • django显示当前时间

    直接用HttpResponse返回一个html标签不太好,如果代码比较多,就不合适了。

    py3study
  • 起薪12500的Python,为什么有些人自学几天就放弃了?

    其实你们现在学习编程,包括Python在内的大部分语言,从互联网都能找到大量的资料,也许有人会说:“资料太多,不知道如何系统地学习”;那给你们讲讲我们当时是怎么...

    一墨编程学习
  • 斯坦福大学《机器学习》课程-中文版笔记(3.1)

    AI传送门
  • PHP 开发学习[4] —— 学习参考网站

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

    泥豆芽儿 MT
  • 技术学习中的三个有趣的数字

    今天聊聊我在近些年技术学习中观察到的一个有趣的现象,是三组数字:50%,90%,5%。

    jeanron100
  • 斯坦福大学《机器学习》课程-中文版内容(9.5)

    AI传送门
  • 《学习之道》第5章 预防拖延

    yeedomliu
  • 斯坦福大学《机器学习》课程-中文版笔记(2.3)

    AI传送门

扫码关注云+社区

领取腾讯云代金券