6.2 【基础】如何抛出和捕获异常?¶
1. 如何抛出异常?¶
异常的产生有两种来源:
一种是程序自动抛出,比如
1/0
会自动抛出 ZeroDivisionError一种是开发者主动抛出,使用
raise
关键字抛出。
在 Python 中是使用 raise
关键字来抛出异常的,比如在下面这个函数中,如果不存在目标文件,则会抛出一个
Exception 通用异常。
def demo_func(filename):
if not os.path.isfile(filename):
raise Exception
2. 如何捕获异常?¶
出现错误或者异常没有关系,关键在于你要学会预判程序可能会出现的错误或异常,然后在代码中捕获这些异常并处理。
异常的捕获的语法有如下四种:
第二种语法¶
不但捕捉了还要获取异常信息,赋值给 e 后,后面你可以把异常信息打印到日志中。
try:
代码A
except [EXCEPTION] as e:
代码B
有了上面的基础语法,可以扩展出下面三种常用的异常捕获的写法。
第三种语法¶
正常使用 try ... except ...
如果代码A发生了异常,则会走到代码B的逻辑。
try:
代码A
except [exception] as e :
代码B
举个例子
>>> try:
... 1/0
... except ZeroDivisionError as e:
... print("发生了异常:错误信息如下: \n" + str(e))
...
发生了异常:错误信息如下:
integer division or modulo by zero
第四种语法¶
使用 try ... except ... else
如果代码A发生了异常,则会走到代码B的逻辑,如果没有发生异常,则会走到代码C
try:
代码A
except [exception] as e:
代码B
else:
代码C
举个例子
不发生异常的情况
>>> try:
... 4/2
... except ZeroDivisionError as e:
... print("发生了异常:错误信息如下: \n" + str(e))
... else:
... print("程序正常运行")
...
2
程序正常运行
发生异常的情况
>>> try:
... 1/0
... except ZeroDivisionError as e:
... print("发生了异常:错误信息如下: \n" + str(e))
... else:
... print("程序正常运行")
...
发生了异常:错误信息如下:
integer division or modulo by zero
第三种:使用
try ... except ... finally
如果代码A发生了异常,则会走到代码B的逻辑,最后不管有没有发生异常都会走到代码C
try:
代码A
except [exception] as e:
代码B
finally:
代码C
举个例子
发生异常的情况
>>> try:
... 1/0
... except ZeroDivisionError as e:
... print("发生了异常:错误信息如下: \n" + str(e))
... finally:
... print("程序运行结束!!")
...
发生了异常:错误信息如下:
integer division or modulo by zero
程序运行结束!!
不发生异常的情况
>>> try:
... 4/2
... except ZeroDivisionError as e:
... print("发生了异常:错误信息如下: \n" + str(e))
... finally:
... print("程序运行结束!!")
...
2
程序运行结束!!
3. 捕获多个异常?¶
每个except捕获一个异常¶
一个 try 语句可能有多个 except 子句,以指定不同异常的处理程序,但是最多会执行一个处理程序。
当代码 A 在运行中抛出了异常时,Python
解释器会逐行运行代码,如果抛出的异常是 exception1
那么后面直接运行代码B,运行完 B 后,就不会再判断后面两个 except 语句了。
而如果不是 exception1
,而是 exception2
,那会运行代码C,而不会再运行第三个 except 语句了。
try:
代码A
except [exception1] as e:
代码B
except [exception2] as e:
代码C
except [exception3] as e:
代码D
举个例子吧,下面这段代码,由于 1/0
会抛出 ZeroDivisionError
错误,所以前面两个异常匹配都不成功,而在最后一个 except
成功匹配上,最终打印出 除数不能为 0
try:
1/0
except IOError:
print("IO读写出错")
except FloatingPointError:
# 浮点计算错误
print("计算错误")
except ZeroDivisionError:
# 除数不能为 0
print("计算错误")
# output: 计算错误
一个except捕获多个异常¶
上面的例子可以看出来,第二个异常和第三个异常是属于同一类,就是
计算错误
,异常处理的代码是一样的,那有没有办法将它们合并在一起呢,简化一下代码呢?
答案是,可以的。
在 except 后面其实是可以接多个异常的,多个异常之间使用括号包裹。只要匹配上一个就算捕获到,就会进入相应的代码分支。
try:
1/0
except IOError:
print("IO读写出错")
except (ZeroDivisionError, FloatingPointError):
print("计算出错")
# output: 计算错误