因为错误也是一个类,捕获一个错误就是捕获到该类的一个实例
因此,错误并不是凭空产生的,而是有意创建并抛出的
Python的内置函数会抛出很多类型的错误,自定义函数也可抛出错误
自定义错误
如果要抛出错误,首先根据需要,可以定义一个错误类,选择好继承关系,然后,用raise语句抛出一个错误的实例
必要时可自定义错误类型,但尽量使用Python内置的错误类型
class FooError(ValueError): #继承Python内置错误类型ValueError
pass
def foo(s):
n = int(s)
if n==0:
raise FooError('invalid value: %s' % s)
return 10 / n
foo('0')
#输出:
Traceback (most recent call last):
File "err_throw.py", line 11, in <module>
foo('0')
File "err_throw.py", line 8, in foo
raise FooError('invalid value: %s' % s)
__main__.FooError: invalid value: 0
连续抛错误
捕获错误目的只是记录一下,便于后续追踪,当前函数不知道应该怎么处理该错误时,就要继续往上抛,让顶层调用者去处理该错误
若顶层调用者还无法知道如何处理时,就继续向上抛,直到错误得到正确解决,否则程序会中止
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()函数中已经捕获了错误,但打印一个ValueError!后,又把错误通过raise语句抛出去了
bar()
关于raise
raise语句如果不带参数,就会把当前错误原样抛出
try:
10 / 0
except ZeroDivisionError:
raise
在except中raise一个Error,还可以把一种类型的错误转化成另一种类型
只要是合理的转换逻辑就可以,但是,决不应该把一个IOError转换成毫不相干的ValueError
try:
10 / 0
except ZeroDivisionError:
raise ValueError('input error!')