6.1 异常处理
Python中使用try语句来处理异常,和其他语句一样,try也要使用缩进结构,try语句也有一个可选的else语句块。try语句结构如下
try:
<语句(块)>
except<异常名1>:
<语句(块)>
except <异常名2>:
<语句(块)>
......
else:
<语句(块)>
finally:
<语句(块)>
该语句的执行流程图如下
例子:
def testTry(index,flag=False):
stulst={'John','Jenny','Tom'}
if flag:
try:
astu=stulst[index]
except IndexError:
print("IndexError")
return "Try Test Finished!"
else:
astu=stulst[index]
return "No Try Test Finished!"
print("Right params testing start...")
print(testTry(1,True))
print(testTry(1,False))
print("Error params testing start...")
print(testTry(4,True))
print(testTry(4,False))
6.2 Python 主要的内置异常及其处理
在python中常见的异常都已经预定义好了 如下:
- AttributeError 调用不存在的方法引发的异常
- EOFError 遇到文件末尾引发的异常
- ImportError 导入模块出错引发的异常
- IndexError 列表越界引发异常
- IOError I/O操作引发的异常,如打开文件出错等
- KeyError 使用字典中不存在的关键字引发的异常
- NameError 使用不存在的变量名引发的异常
- TabError 语句块锁紧不正确引发的异常
- ValueError 搜索列表中不存在的值引发的异常
- ZeroDivisionError 除数为零引发的异常
except语句主要有一下几种用法。
- except: #捕获所有异常
- except<异常名>: #捕获指定异常:
- except(异常名1,异常名2): # 捕获异常名1 或者异常名2
- except<异常名>as<数据>: # 捕获指定异常及其附加的数据
- except(异常名1,异常名2)as<数据>: # 捕获异常名1或异常名2及异常的附加数
例子:
def testTryAll(index,i):
stulst=["John","Jenny","Tom"]
try:
print(len(stulst[index])/i)
except:
print("Error!")
print('Try all...Right')
testTryAll(1,2)
print('Try all...one Error')
testTryAll(1,0)
print('Try all...two Error')
testTryAll(4,0)
说明,代码中定义了函数 testTryAll, try语句中捕获了所有异常。第三次测试中发生了越界异常和除0异常。
例子2:
def testTryOne(index,i):
stulst=["John","Jenny","Tom"]
try:
print(len(stulst[index])/i)
except IndexError:
print("Error!")
print('Try one...Right')
testTryOne(1,2)
print('Try one...one Error')
testTryOne(4,2)
print('Try one...one Error')
testTryOne(1,0)
代码中定义了方法testTryOne,其try语句中只捕获了指明的IndexError异常,因此当程序引发indexError时,程序不会中断,二挡引发除0异常时程序会中断。
6.3 手工抛出异常
6.3.1用raise手工抛出异常
使用raise引发异常十分简单,raise有以下几种使用方式
- raise 异常名
- raise 异常名,附加数据
- raise 类名
例子:
def testRaise():
for i in range(5):
try:
if i==2:
raise NameError
except NameError:
print('Raise a NameError')
print(i)
print('end...')
testRaise()
6.3.2 assert 语句
assert语句一般形式如下:
assert<条件测试>,<异常附加数据> #其中异常附加数据是可选的
assert语句时简化的raise,它引发异常的前提是其后面的条件测试为假
例子:
def testAssert():
for i in range(3):
try:
assert i<2
except AssertionError:
print('Raise a AssertionError!')
print(i)
print('end...')
testAssert()
6.3.3 自定义异常类
class MyError(Exception): #继承Exception类
pass
实例:
class RangeError(Exception):
def __init__(self,value):
self.value=value
def __str__(self):
return self.value
raise RangeError('Range error!')
6.4.1调试语句块函数
pdb模块中的调试语句块的函数及参数原型为:
run(statement[,globals[, locals]])
- statement 要调试的语句块,以字符串的形式表示
- globals 可选参数,设置statement运行的全局环境变量:
- locals 可选参数,设置statement运行的局部环境变量。
例子:
import pdb
pdb.run("""
for i in range(3):
print(i)
""")
pdb交互命令
6.4.2 调试函数
pdb模块中的调试函数应当调用模块中的runcall函数,
runcall(function[,argument,...])
- function 函数名:
- argument 函数的参数
例子:
import pdb
def sum(maxint):
s=0
for i in range(maxint):
s+=i
return s
pdb.runcall(sum,10)
代码中调用pdb模块runcall函数来调试自定义函数sum,然后调用pdb.runcall对其进行交互调试
提示符中指明了运行的文件,函数及当前语句行内容,并且可以多次调用和调试
6.5.1 用testmod函数测试
用testmod函数进行单元测试,就要将测试用例写入程序的docstring 中然后可以用两种方法进行测试。
例子:
(交互模式)
import pdb
defgrade(sum):
"""
>>>grade(100)
'优秀'
>>>grade(65)
'合格'
>>> grade(10)
'不合格'
"""
if sum > 90:
return '优秀'
if sum >80:
return '良'
if sum >60:
return '合格'
if sum<60:
return '不合格'
if name == '__main__':
import doctest
doctest.testmod()
6.5.2 用testfile函数测试
例子
import pdb
def grade(sum):
if sum > 90:
return '优秀'
if sum >80:
return '良'
if sum >60:
return '合格'
if sum<60:
return '不合格'
保存上述代码为文件 test.py
然后在交互中
>>>grade(100)
'优秀'
>>>grade(65)
'合格'
>>> grade(10)
'不合格'