【Python】初学自用笔记 第十一篇 错误、调试和测试

  • 错误:包括程序编写错误、用户输入错误、客观条件引起的错误

  • 调试:跟踪程序的执行,查看每一步变量的值是否正确

  • 测试:编写测试用来反复运行程序,确保程序输出符合我们编写的测试

错误处理

try

在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误码,如果由我们自己编写,那会很繁杂,幸好python内置了一套try...except...finally..的错误处理机制:

try:
    print('try...')
    r=10/int('2')
    print('result:',r)
except ZeroDivisionError as e:  #如果try语句出现了错误,except就会判断是否为某种错误
    print('except:',e)
except ValueError as e:  #错误类型还有很多种,但是只用同一种代码e来表示
    print('except:',e)
else:  #若没有出现错误,使用else语句打印无误提示
    print('no error!')
finally:  #无论上面1有没有出现错误1,finally语句都会执行
    print('finally...')
print('END')
'''
try...
result: 5.0
no error!
finally...
END
'''

调用栈

如果没有使用try来捕获错误,错误就会一直向上抛,最被python解释器捕获,打印出错误信息,我们通过分析信息来定位错误:

def foo(s):
    return 10/int(s)
def bar(s):
    return foo(s)*2
def main():
    bar('0')
print(main())
'''
Traceback (most recent call last):  #这是错误的跟踪信息
  File "C:\Users\ASUS\PycharmProjects\pythonProject1\11.6.py", line 840, in <module>  
    print(main())  #调用main出错了,在代码的第840行
  File "C:\Users\ASUS\PycharmProjects\pythonProject1\11.6.py", line 839, in main
    bar('0')  #调用bar出错了,在代码的第839行
  File "C:\Users\ASUS\PycharmProjects\pythonProject1\11.6.py", line 837, in bar
    return foo(s)*2  #return foo(s)*2这个语句出错了,在第837行
  File "C:\Users\ASUS\PycharmProjects\pythonProject1\11.6.py", line 835, in foo
    return 10/int(s)  #return 10/int(s)这个语句出错了,下面没有类似的错误信息,说明这是错误的源头
ZeroDivisionError: division by zero  #错误源头的错误类型就是0作除数
'''

记录错误

python内置的logging模块可以很容易地记录错误信息:

import logging
def foo(s):
    return 10/int(s)
def bar(s):
    return foo(s)*2
def main():
    try:
        bar('0')
    except Exception as e:
        logging.exception(e)  #在显示错误的同时,将错误记录到日志里
main()
print('END')

抛出错误

用raise抛出自己定义的错误示例:

class FooError(ValueError):
    pass
def foo(s):
    n=int(s)
    if n==0:
        raise FooError('invalid value:%s' %s)  
    return 10/n
print(foo('0'))

只有在必要时才定义我们自己错误类型,尽量使用python内置的错误类型。

还可以先捕获错误、打印出来,再用raise语句将错误向上抛,因为有时候一些错误单靠自己解决不了,需要抛给能解决错误的人来解决:

def foo(s):
    n=int(s)
    if n==0:
        raise ValueError('invald value:%s' % s)
    return 10/n
def bar():
    try:
        foo('0')
    except ValueError as e:
        print('ValueError!')
        raise  #raise语句若不带参数,就会把当前错误原样抛出
bar()

此外,在except中的raise还可以将错误转化成另一种类型:

try:
    10/0
except ZeroDivisionError:  #不用再写 as e
    raise ValueError('input error!')

调试

程序运行中难免会出现错误,就需要一套调试程序来对运行中变量的值进行检测,从而修复bug。

断言 assert

def foo(s):
    n=int(s)
    assert n!=0,'n is zero!'  #表达式 n!=0 应该是 True,否则后面的代码一定会出错,若断言失败,assert语句就会抛出后面那句话
    return 10/n
def main():
    foo('0')

可以在启动python解释器时用参数 -O 来关闭assert,之后遇到的assert都可以看成pass语句。

logging

import logging
logging.basicConfig(level=logging.INFO)  #指定记录信息的级别
s='0'
n=int(s)
logging.info('n=%d' % n)  #输出错误原因,并上传到日志
print(10/n)

日志等级说明:

  • DEBUG:程序调试bug时使用

  • INFO:程序正常运行时使用

  • WARNING:程序未按预期运行时使用,但并不是错误,如:用户登录密码错误

  • ERROR:程序出错误时使用,如:IO操作失败

  • CRITICAL:特别严重的问题,导致程序不能再继续运行时使用,如:磁盘空间为空,一般很少使 用

  • 默认的是WARNING等级,当在WARNING或WARNING之上等级的才记录日志信息。

  • 日志等级从低到高的顺序是: DEBUG < INFO < WARNING < ERROR < CRITICAL

pdb

pdb是python交互模式可以使用的一种调试器。准备好程序后,在对话框中输入:

$ python -m pdb err.py

就启动了pdb调试器,接下来可以输入不同的命令来查看或执行:

  • 输入命令 1 :查看代码

  • 输入命令 n :单步执行代码

  • 输入命令 p 变量名 :查看变量

  • 输入命令 q :结束调试,退出程序

pdb.set_trace()

  • 这个方法是用来设置断点,检查断点上方的程序,只需要先加载pdb模块,在程序中合适的地方插入pdb.set_trace()

  • 之后运行代码时,程序会自动在插入的地方暂停并进入pdb调试环境,可以用p查看变量,也可以用c继续运行。

IDE

一个插件,用来调试十分方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值