- 异常处理结构
当程序执行过程中出现错误时Python会自动引发异常,程序元也可以通过raise语句显示的引发异常。异常处理是因为程序执行过程中由于输入不合法导致程序出错而在正常控制流之外采取的行为。
# Python内置异常类层次结构
BaseException是所有内置异常类的基类。在使用异常处理结果捕获和处理异常时,应尽量具体一点,最好是明确指定要捕获和处理哪一类异常。建议先尝试捕获派生类,然后再捕获基类,应尽量直接捕获Exception或BaseException.
# 异常处理结构
1、try……except……
最简单的异常结构处理形式,try子句中的代码包含可能会引发异常的语句,except子句用来捕捉相应的异常。如果try子句语句引发异常,被except捕获,则执行except中语句;没有异常直接执行以下代码;如果出现异常但没有被捕获则往外跑出,所有层都没捕获则抛出异常。
2、try……except……else……
带有else子句的异常处理结构可以看做一种特殊的双分支选择结构,如果try中的代码抛出了异常并且被except语句捕捉则执行相应的异常处理代码,这种情况下就不会执行else中的代码;如果try中的代码没有引发异常,则执行else块的代码。(不要把太多代码放在try中,而是应该只放真的可能会引发异常的代码)
while True:
x = input('Please input:')
try:
x = int(x)
except Exception as e:
print('Error.')
else:
print('You have input {0}'.format(x))
break
3、try……except……finally……
在这种结构中,无论try中的代码是否发生异常,也不管抛出的异常有没有被except捕获,finally子句中的代码总会得到执行。所以,finally中的代码常用来做一些清理工作,例如释放try子句中代码申请的资源。
def div(a,b):
try:
print(a/b)
except ZeroDivisionError:
print('The second parameter cannot be 0.')
finally:
print(-1)
div(3,5)
print('='*30)
div(3,0)
0.6
-1
==============================
The second parameter cannot be 0.
-1
需要注意的是,异常处理结构不是万能的,并不是采用了异常处理结构就万事大吉,finally子句中的代码也可能会引发异常。
4、可以捕捉多种异常的异常处理结构
语法格式为:
try:
# 可能会引发异常的代码
except Exception1:
# 处理异常类型1的代码
except Exception2:
# 处理异常类型2的代码
except Exception3:
# 处理异常类型3的代码
try:
x = float(input('请输入被除数:'))
y = float(input('请输入除数:'))
z = x/y
except ZeroDivisionError:
print('除数不能为0')
except TypeError:
print('被除数和除数应为数值类型')
except NameError:
print('变量不存在')
else:
print(x,'/',y,'=',z)
为了减少代码量,Python允许把多个异常类型放到一个元组中,然后使用一个except子句同时捕捉多种异常。(except(ZeroDivisionError,TypeError,NameError))
5、可同时包含else子句、finally子句和多个except子句的异常处理结构
# 断言与上下文管理语句
断言语句assert也是一种比较常用的技术,常用来在程序的某个位置确认某个条件必须满足。断言语句assert仅当脚本的__debug__属性值为True时有效,一般只在开发区和测试阶段使用。当使用优化选项-o或-oo把Python程序编译为字节码文件时,assert语句将被删除。
a = 3
b = 5
assert a == b,'a must be equal to b'
上下文管理(context manager)语句with可以自动管理资源,不论因为山么原因(哪怕是代码引发了异常)跳出with块,总能保证文件被正确关闭,并且可以在代码块执行完毕后自动还原进入该代码块时的现场,常用于文件操作、数据库连接、网络通信连接和多个线程、多进程同步等场合。
- 单元测试 unittest
软件测试对于保证软件质量真的很重要。
软件测试的方法有很多,从软件工程角度来讲,可以分为白盒测试和黑盒测试两大类。其中,白盒测试主要是通过阅读程序源代码来判断是否符合功能要求,对于复杂的业务逻辑白盒测试难度非常大,一般以黑盒测试为主,白盒测试为辅。黑盒测试不关心模块内部实现方式,只关心,只关心其功能是否正确,通过精心设计一些测试用例来检验模块的输入和输出是否正确,最终判断是否符合预定的功能要求。
Python标准库unittest提供了大量用于单元测试的类和方法,其中最常用的是TestCase类,如下表:
方法名称 | 功能说明 | 方法名称 | 功能说明 |
assertEqual(a,b) | a == b | assertNotEqual(a,b) | a != b |
assertTrue(X) | bool(X) is True | assertFalse(X) | bool(X) is False |
assertIs(a,b) | a is b | assertIsNot(a,b) | a is not b |
assertIn(a,b) | a in b | assertNotIn(a,b) | a not in b |
assertIsNone(x) | x is None | assertNotNone(x) | x is not None |
assertIsInstance(a,b) | isinstance(a,b) | assertNotIsInstance(a,b) | not isintance(a,b) |
assertAlmostEqual(a,b) | round(a-b,7) == 0 | assertNotAlmostEqual(a,b) | round(a-b,7) != 0 |
assertGreater(a,b) | a > b | assertGreaterEqual(a,b) | a >= b |
assertLess(a,b) | a < b | assertLessEqual(a,b) | a <= b |
assertRegex(s,r) | r.search(s) | assertNotRegex(s,r) | not r.search(s) |
setUp() | 每项测试开始之前自动调用该函数 | tearDown() | 每项测试完成之后自动调用该函数 |