1.错误处理
1) 捕获异常
使用try….except…else…finally…进行捕获异常
exp:
try:
print('try...')
r = 10 / int('2')
print('result:', r)
except ValueError as e:
print('ValueError:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
else:
print('no error!')
finally:
print('finally...')
print('END')
2)抛出异常 raise
exp:
# err_raise.py
class FooError(ValueError):
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)
return 10 / n
foo('0')
2.调试
1) 使用print()打印
def foo(s):
n = int(s)
print('>>> n = %d' % n)
return 10 / n
def main():
foo('0')
main()
打印出的
$ python3 err.py
>>> n = 0
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero
2)使用assert 断言
语法:assert 表达式 字符串
表达式为真时继续执行下面的步骤 否则打印后面的字符串
exp:
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
def main():
foo('0')
执行结果:
$ python3 err.py
Traceback (most recent call last):
...
AssertionError: n is zero!
ps:
使用python -O xx.py 关闭assert
3)使用日志logging
import logging
logging.basicConfig(level=logging.INFO)
s = '0'
n = int(s)
logging.info('n = %d' % n)
print(10 / n)
输出结果
$ python3 err.py
INFO:root:n = 0
Traceback (most recent call last):
File "err.py", line 8, in <module>
print(10 / n)
ZeroDivisionError: division by zero
4)使用调试器pdb
启动Python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态
exp:
# err.py
s = '0'
n = int(s)
print(10 / n)
$ python3 -m pdb err.py
> /Users/michael/Github/learn-python3/samples/debug/err.py(2)<module>()
-> s = '0'
输入 l 可以查看代码 (小写L)
(Pdb) l
1 # err.py
2 -> s = '0'
3 n = int(s)
4 print(10 / n)
输入命令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)
任何时候都可以输入命令 p 变量名 来查看变量:
(Pdb) p s
'0'
(Pdb) p n
0
输入命令q结束调试,退出程序:
(Pdb) q
5)pdb.set_trace()断点调试
在可能出现异常的地方加上pdb.set_trace()
exp:
import pdb
s = '0'
n = int(s)
pdb.set_trace()
print(10 / n)
使用python xx.py运行
程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行
$ python3 err.py
> /Users/michael/Github/learn-python3/samples/debug/err.py(7)<module>()
-> print(10 / n)
(Pdb) p n
0
(Pdb) c
Traceback (most recent call last):
File "err.py", line 7, in <module>
print(10 / n)
ZeroDivisionError: division by zero
3.单元测试
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作
1) 编写单元测试时首先编写一个测试类 从unittest.TestCase继承
2)编写测试方法 一定要以test开头
使用assertEqual()或者assertRaises(xxError)测试
3)setUp() 和 tearDown() 分别在测试开始前和结束后运行
3)运行单元测试
1. python xxxtest.py
2. python -m unittest xxxtest.py [推荐]
exp:
编写一个需要测试的类 Dict
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
编写测试类和测试方法
import unittest
from mydict import Dict
class TestDict(unittest.TestCase):
def setUp(self):
print("setUp...")
def tearDown(self):
print("tearDown...")
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["eee"]
def test_attrerror(self):
d=Dict()
d["key"]="value"
with self.assertRaises(AttributeError):
value=d.eee
if __name__ == '__main__':
unittest.main()
运行结果
$ python3 -m unittest mydict_test
.....
----------------------------------------------------------------------
Ran 5 tests in 0.000s
OK
3.文档测试
exp:
def abs(n):
'''
Function to get absolute value of number.
Example:
>>> abs(1)
1
>>> abs(-1)
1
>>> abs(0)
0
'''
return n if n >= 0 else (-n)
运行无输出说明测试通过