Task08:异常处理(1day)
1.python 标准异常
错误类型 | 说明 |
---|---|
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
IndexError | 序列中没有此索引(index) |
IndentationError | 缩进错误 |
ImportError | 导入模块/对象失败 |
NameError | 未声明/初始化对象 (没有属性) |
OSError | 输入/输出操作失败 |
StopIteration | 迭代器没有更多的值 |
ValueError | 传入无效的参数 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
2.异常处理
高级语言通常都内置了一套try…except…finally…的错误处理机制,Python也不例外。
try
让我们用一个例子来看看try的机制:
try:
print('try...')
r=10/0
print('result:',r)
except ZeroDivisionError as e:
print('except:',e)
finally:
print('finally...')
print('end')
当我们认为某些代码可能会出错时,就可以用try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即except语句块,执行完except后,如果有finally语句块,则执行finally语句块,至此,执行完毕。
上面的代码在计算10 / 0时会产生一个除法运算错误,具体的结果如下:
try...
except: division by zero
finally...
end
从输出可以看到,当错误发生时,后续语句print(‘result:’, r)不会被执行,except由于捕获到ZeroDivisionError,因此被执行。最后,finally语句被执行。然后,程序继续按照流程往下走。
如果把除数0改成2,则执行结果如下:
try...
result: 5.0
finally...
end
由于没有错误发生,所以except语句块不会被执行,但是finally如果有,则一定会被执行(可以没有finally语句)。
错误应该有很多种类,如果发生了不同类型的错误,应该由不同的except语句块处理。没错,可以有多个except来捕获不同类型的错误:
try:
print('try...')
r=10/int('a')
print('result:',r)
except ValueError as e:
print('ValueError:',e)
except ZeroDivisionError as e:
print('ZeroDivisionError:',e)
finally:
print('finally...')
print('end')
实现如下:
try...
ValueError: invalid literal for int() with base 10: 'a'
finally...
end
int()函数可能会抛出ValueError,所以我们用一个except捕获ValueError,用另一个except捕获ZeroDivisionError。
此外,如果没有错误发生,可以在except语句块后面加一个else,当没有错误发生时,会自动执行else语句:
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')
try...
result: 5.0
no error!
finally...
end
Python的错误其实也是class,所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。比如:
try:
foo(2)
except ValueError as e:
print('ValueError')
except UnicodeError as e:
print('UnicodeError')
使用try…except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用foo(),foo()调用bar(),结果bar()出错了,这时,只要main()捕获到了,就可以处理:
def foo(s):
return 10/int(s)
def bar(s):
return foo(s)*2
def main():
try:
bar('0')
except Exception as e:
print('Error:',e)
finally:
print('finally...')
小结:
Python内置的try…except…finally用来处理错误十分方便。出错时,会分析错误信息并定位错误发生的代码位置才是最关键的。
程序也可以主动抛出错误,让调用者来处理相应的错误。但是,应该在文档中写清楚可能会抛出哪些错误,以及错误产生的原因。