10.错误、调试和测试
10.1错误处理
try...catch
机制
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
else:
print('no error!') #如果没有错误发生
finally:
print('finally...')
print('END')
-
所有的错误类型都继承自
BaseException
-
调用栈:如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出
-
记录错误:
logging
模块,还可以把错误日志记录到文件里方便排查
# err_logging.py
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
(如果不带参数就抛出原错误,还可以把一个错误转为另一种类型)
def foo(s):
n = int(s)
if n==0:
raise ValueError('invalid value: %s' % s)
return 10 / n
def bar():
try:
foo('0')
except ValueError as e:
print('ValueError!')
raise
bar()
10.2调试
- print()调试
- assert()(可以用python -O err.py关闭)
def foo(s):
n = int(s)
assert n != 0, 'n is zero!' # 若条件不满足,就抛出AssertionError错误
return 10 / n
def main():
foo('0')
- logging,不会抛出错误,可以输出到文件,允许你指定记录信息的级别,有
debug
,info
,warning
,error
等几个级别
import logging
logging.basicConfig(level=logging.INFO)
- pdb,Python的调试器,让程序以单步运行,随时查看运行状态
$ python -m pdb err.py
> /Users/michael/Github/learn-python3/samples/debug/err.py(2)<module>()
-> s = '0'
(Pdb) l
1 # err.py
2 -> s = '0'
3 n = int(s)
4 print(10 / n)
(Pdb) n
> /Users/michael/Github/learn-python3/samples/debug/err.py(3)<module>()
-> n = int(s)
(Pdb) n
> /Users/michael/Github/learn-python3/samples/debug/err.py(4)<module>()
-> print(10 / n)
(Pdb) p s # 输入命令p 变量名来查看变量
'0'
(Pdb) p n # 输入命令q结束调试,退出程序
0
(Pdb) q
- pdb.set_trace(),只需要
import pdb
,在可能出错的地方放一个pdb.set_trace()
- IDE
10.3单元测试(unit_test)
- 编写需要测试的类
class Dict(dict):
def __init__(self, **kw):
super().__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
- 编写测试类,测试函数必须以test_xxx()开头
import unittest
from mydict import Dict
class TestDict(unittest.TestCase): # 测试类,从unittest.TestCase继承
def test_init(self):
d = Dict(a=1, b='test')
self.assertEqual(d.a, 1)
self.assertEqual(d.b, 'test')
self.assertTrue(isinstance(d, dict))
def test_key(self):
d = Dict()
d['key'] = 'value'
self.assertEqual(d.key, 'value')
def test_attr(self):
d = Dict()
d.key = 'value'
self.assertTrue('key' in d)
self.assertEqual(d['key'], 'value')
def test_keyerror(self):
d = Dict()
with self.assertRaises(KeyError):
value = d['empty']
def test_attrerror(self):
d = Dict()
with self.assertRaises(AttributeError):
value = d.empty
-
常用的断言
-
assertEqual()
self.assertEqual(abs(-1), 1) # 断言函数返回的结果与1相等
-
assertRaises()
with self.assertRaises(KeyError): value = d['empty']
-
-
运行单元测试
if __name__ == '__main__':
unittest.main()
# or
python mydict_test.py
# or
python -m unittest mydict_test
- setUp与tearDown,这两个方法会分别在每调用一个测试方法的前后分别被执行
10.4文档测试doctest
-
Python内置的“文档测试”(doctest)模块可以直接提取注释中的代码并执行测试
-
e.g.
# mydict2.py
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()
- 比如把
__getattr__()
方法注释掉,再运行就会报错
$ python mydict2.py
**********************************************************************
File "/Users/michael/Github/learn-python3/samples/debug/mydict2.py", line 10, in __main__.Dict
Failed example:
d1.x
Exception raised:
Traceback (most recent call last):
...
AttributeError: 'Dict' object has no attribute 'x'
**********************************************************************
File "/Users/michael/Github/learn-python3/samples/debug/mydict2.py", line 16, in __main__.Dict
Failed example:
d2.c
Exception raised:
Traceback (most recent call last):
...
AttributeError: 'Dict' object has no attribute 'c'
**********************************************************************
1 items had failures:
2 of 9 in __main__.Dict
***Test Failed*** 2 failures.
参考教程
(转载整理自网络,如有侵权,联系本人删除,仅供技术总结使用)