错误处理
Python中的try
try:
...
except 错误类型1 as e:
...
except 错误类型2:
...
else:
...
finally: #可缺省,一定会被执行
....
- `try…except“`可以跨越多层调用,这是一个极大的便利;
- 所有的错误类型都继承自错误基类
BaseException,捕捉到的错误类型会将这种类型的子类也全部捕获,因此如果一个exception错误类型后还有一个exception子类错误类型,则后者不会被捕获。
打印调用堆栈
先import logging,再在except块中使logging.exception(e),则可以将错误堆栈打印出,然后继续执行程序。也可以将以上信息写入文件,实现方法在IO一章再做整理。
抛出错误
如果要自己定义错误类型FooError,则要设置好它继承自哪一个父类,然后用raise FooError(...)抛出错误。不过尽量用Python内置的错误类型。raise语句如果不带参数,会把当前错误原样抛出,让上一级调用处理。
调试
断言经常用在调试中,python的断言格式是assert 表达式。而且Python有个方法可以跳过所有断言$ python3 -O err.py其中的参数-0就是跳过断言的解释器启动参数
logging
上一节提到logging可以记录和输出错误,使用logging调试显然也是可以的。可以使用logging.info(...)输出调试信息,而且logging有个功能,在import logging下一行添加logging basicConfig(level = logging.INFO)可以定义信息处理的级别,如debug, info, warning, error等。低于该级别的信息就不会起作用了。
其他方法
至于更多的调试方法,比如单步运行等,还是使用IDE方便,这里就不整理了
单元测试
- 单元测试需要首先
import unittest。 - 还要引入需要测试的类或函数。
- 然后定义一个单元测试类,从
unittest.TestCase父类继承,并且包含各种测试方法。 - 测试方法需要以
test_开头。一般使用不同形式的断言来判断结果,如self.assertTrue(...)、self.assertEqual(...)等。还可以抛出指定断言错误:
#抛出表达式对应的错误
with self.assertRaises(错误类型):
表达式
运行单元测试
在在单元测试的模块最后加上下列代码:
if __name__ = '__main__':
unittest.main()
这样就可以把该模块内的代码作为正常Python脚本运行。
在命令行中使用$ python3 -m unittest 测试模块名可以更方便地运行单元测试,而且可以实现批量单元测试
两个用于单元测试的特殊函数
setUp()和tearDown(),在每调用一个测试方法的前后被执行。这样就可以将文件读写等操作放到这两个函数里,简化其他方法的代码。
文档测试
执行写在注释里的代码。Python内置的文档测试doctest模块可以直接提取主时钟的代码并执行测试。比如下面对阶乘函数进行文档测试的代码:
#fdt.py
def fact(n):
'''
test fact function
>>> fact(1)
1
>>> fact(0)
Traceback (most recent call last):
...
ValueError: '0'
>>> fact(-1)
Traceback (most recent call last):
...
ValueError: '-1'
>>> fact(2)
2
>>> fact(5)
120
'''
if n < 1:
raise ValueError()
if n == 1:
return 1
return n*fact(n-1)
if __name__ == '__main__':
import doctest
doctest.testmod()
在命令行中执行,将会输出测试的信息。在根据教程编写这段程序的时候执行遇到了大量错误,最后发现是一个非常细节的地方没注意到:
文档测试的注释部分,>>>后边一定要有个空格再写东西:>>> fact(1)空格一定不能少
本文介绍了Python中的错误处理机制,包括try...except语句的使用、打印调用堆栈、抛出错误的方法,以及调试技巧如使用logging和断言。此外,还详细讲解了单元测试和文档测试的实现。
969

被折叠的 条评论
为什么被折叠?



