错误处理
如果发生错误,可以事先约定返回一个错误代码,这样就可以知道是否有错以及原因。eg打开文件的函数open(),成功时返回文件描述符(就是一个整数),出错时返回-1.
用错误码来表示是否出错十分不便。
错误处理机制:try—except—finally
try
try:
xxxxxx
except xxxx as e:
xxxxxx
else:
finally
所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误,会把子类型也一网打尽
Python所有的错误都是从BaseException类派生的,常见的错误类型和继承关系
https://docs.python.org/3/library/exceptions.html#exception-hierarchy
调用栈
如果错误没有被捕获,它会被一直往上抛,最后被python解释器捕获,打印一个错误信息,然后程序退出。
出错的时候,一定要分析错误的调用栈信息,才能定位错误的位置
记录错误
如果不捕获错误,让python解释器打印出错误堆栈,但是程序也被结束了。我们捕获错误就可以把错误堆栈打印出来,然后分析错误原因,同时让程序继续执行下去
py内置的logging模块可以容易地记录错误信息。配置后,logging还可以把错误记录到日志文件里,方便事后排查。
抛出错误
因为错误是class,捕获一个错误就是捕获到该class的一个实例。因此,错误并不是凭空产生的,而是有意创建并抛出的。
如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系然后用raise语句抛出一个错误实例
如果可以选择Python已有的内置的错误类型(比如ValueError,TypeError),尽量使用Python内置的错误类型。
raise语句如果不带参数,就会把当前错误原样抛出。此外,在except中raise一个Error,还可以把一种类型的错误转化成另一种类型
调试
第一种就是在下天天用的。。。用print打印出来变量
断言
用assert代替print
如果断言后面的语句失败 抛出异常语句
最后启用py解释器时可以用-O参数来关闭assert:
$ python -O err.py
关闭后所有的assert语句当成pass来看
logging
用logging代替print,比起assert,logging不会抛出错误,而且可以输出到文件
logging的有点:允许指定记录信息的级别,有debug,info,waring,erro几个级别。
import logging
logging.basicConfig(level=logging.INFO)
pdb
第四种启动py的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。
但是太麻烦了。
补充一种调试方法
pdb.set_trace()
也是用pdb,但不需要单步执行,我们只需要import pdb,然后在可能跟出错的地方放一个pdb.set_trace(),就可以设置一个断点。
运行代码,程序会自动在这一行暂停并进入pdb调试模式,可以用命令 p 查看变量,或者用命令c继续运行
更好的调试方式-插件IDE
总结
logging是终极武器的呀。
单元测试
TDD 测试驱动开发
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。
运行单元测试
if name==‘main’:
unittest.main()
第二种方法 命令行通过参数 -m unittest 直接运行 推荐-可以一次
setUp与tearDown
这两个方法会分别在每调用一个测试方法的前后分别被执行。
如果测试需要启动一个数据库,可以在setUp()方法中连接数据库,在tearDown()方法中关闭数据库,这样不必在每个测试方法中重复相同的代码。