Python | 异常处理

try, raise, except

try, raise, except

1. try except

在使用这种异常处理时需要注意,try 中的代码不要过于复杂,因为过多的代码容易导致定位异常变得十分困难。

同时,也不要单独使用一个 except 来捕获,否者错误定位容易出错。原因有,一、异常有很多种类,一个 except 可能捕捉不到;二、在 Python 中各种异常是内建的,具有一定的继承结构,所以父类异常一般要写得靠后,子类异常写得靠前。

通常在循环遍历变量时,如果在 try 语句中出现了异常,我们经常需要忽略异常继续执行 try 中的语句,这时候只需要在 except 后添加 continue 即可。

1
2
3
4
5
6
7
try:
# 需要执行的操作
except () as e:
# 可以依次排列多个异常处理
# 一旦出现错误,即跳出 try except
print(e)
continue:

2. try finally

try finally 语句有一项常见的用途,就是确保能够关闭文件句柄。比如,在写入文件过程中由于找不到文件而导致 IOError,不管怎么样,finally 中的 file.close() 是一定会执行的。

1
2
3
4
5
file = open('file_path', 'w')
try:
file.write("I'm the best programmmer!")
finally:
file.close()

在阅读《编写高质量代码——改善python程序的91个建议》这本书的时候,书中有讲到在使用 try-finally 语句时,在 finally 中有个地方很容易出错。比如,在 finally 中使用 return 进行返回:

1
2
3
4
5
6
7
8
9
10
11
def try_finally(a):
try:
if a < 0:
raise ValueError("输入不能为负")
# 当 a = 2 过了 if 判断语句,else 语句并不会执行
else:
return a
except ValueError as e:
print(e)
finally:
return -1

当输入为 -1 时,执行程序会抛出异常并且返回 -1。当输入为 2 的时候,想当然程序应该会返回 2。其实不然,当程序运行到 else 语句之前会先执行 finally 中的 return 语句,所以没等到先执行 else 语句,程序就提前结束了。

1
2
3
4
5
try:
# 需要执行的操作
finally:
# 无论 try 中发生了什么
# finally 后的语句都会执行

3. raise exception

如果在捕获异常之后要显示重复地抛出,特别是当你觉得系统给出的错误信息不足需要补充,raise 语句能够帮助你做到这一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> try:
... print(1 / 0)
... except:
... raise RuntimeError("Something bad happened")
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
# 除了系统抛出的错误,raise 语句还会重复抛出错误
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

4. 例子

新打开一个文件 test.txt,使用 chmod 取消文件的写入权限(chmod -w test.txt),人为“故意”制造一个错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/python
# -*- coding: UTF-8 -*-
try:
f = open("test.txt", "w")
f.write("this is a test file for error!")
print("success!!!")
# 程序会依次经过两个 except 语句
# 如果没有则忽略
# 本例中的 ZeroDivisionError 显然不会被打印出来
except ZeroDivisionError as e:
print("这是 except 语句,显示除法错误!!!")
except IOError as e:
print("这是 except 语句,显示文件写入错误!!!")
raise
else:
print("没有出现错误,大吉大利!!!")
# 不管最终咋样,finally 语句依旧执行
finally:
print("这是 finally 语句,最终 finally 语句依旧会执行!!!")

推荐阅读

  1. Python Exception Handling - Try, Except and Finally
  2. 菜鸟教程:Python 异常处理
  3. 廖雪峰:错误、调试和测试
觉得还不错?帮我赞助点域名费吧:)