错误处理

try

:

1
2
3
4
5
6
7
8
9
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally...')
print('End')

如果运行try语句块的代码出错, 则跳至错误处理代码, 即except语句块, 执行完后若有finally语句块, 则执行; 如未出错且有finally语句块, 则相继执行

except

语法:

1
2
3
4
except ERRORNAME[, ERRORNAME...] (as ALIAS):
...
[else:
...]

可以添加else子句, 当无错误发生时, 将自动执行

异常类

所有的错误其实也是class, 所有错误类型都继承自BaseException; 同时, 在使用except捕获异常时, 不仅会捕获该类型的错误, 也会捕获其子类异常

常见的异常类型和继承关系

处理错误

记录错误

使用Python内置的 { % post_link 4-模块详解 logging % } 模块可以记录下错误信息, 且让程序继续运行

通过配置, logging还可以把错误记录到日志文件中

抛出错误

可以自定义一个异常的子类, 使用raise语句抛出一个错误的实例

另外在使用try...except...时, 在捕获错误之后仍然可以向上抛出错误

测试

单元测试

单元测试是用来对一个模块, 一个函数或一个类来进行正确性检验的测试工作

引入unittest模块, 创建一个基于unittest.TestCase的测试类, 并在其中编写类似test_xxx()的方法, 同时该类提供了很多内置的条件判断

  1. self.assertEqual(测试表达式, 预计结果) 判断是否相等
  2. with self.assertRaises(KeyError):\n 测试表达式 期望抛出指定类型的Error

在编写好单元测试后, 可以作为一个普通的python脚本运行来测试, 也可以在命令行通过参数-m unittest直接运行单元测试; 推荐后一种做法, 还可以一次批量运行很多单元测试

setUP与tearDown

在单元测试中可以编写两个特殊的setUp()tearDown()方法, 这两个方法分别会在每调用一个测试方法的前后执行

文档测试

在很多文档中, 都可以看到示例代码, Python也提供了doctest模块来实现自动化的文档测试功能, 它可以提取出注释中符合交互式命令行格式的代码来执行, 确保文档中所写的例子是可运行的

文档测试可以开发者更好地写好注释, 以帮助读者更好地获取该模块的标准输入和输出

:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Dict(dict):
'''
Simple dict but also support access as x.y style.

>>> d1 = Dict()
>>> d1['x'] = 100
>>> d1.x
100
>>> d1.y = 200
>>> d1['y']
200
>>> d2 = Dict(a=1, b=2, c='3')
>>> d2.c
'3'
>>> d2['empty']
Traceback (most recent call last):
...
KeyError: 'empty'
>>> d2.empty
Traceback (most recent call last):
...
AttributeError: 'Dict' object has no attribute 'empty'
'''
def __init__(self, **kw):
super(Dict, self).__init__(**kw)

def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(r"'Dict' object has no attribute '%s'" % key)

def __setattr__(self, key, value):
self[key] = value

if __name__=='__main__':
import doctest
doctest.testmod()