异常
一般情况下在python无法正常处理程序时就会发生一个异常。
异常是python对象,表示一个错误。当python程序发生错误时需要捕获处理,否则程序会终止执行。
异常处理
捕获异常可以使用try/except
语句。
该语句用来检测try
语句块中的错误,从而让except
语句捕获异常信息并处理。
语法规则
1
2
3
4
5
6
7
8
9
10try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
finally:
<语句> #不管如何,最后一定执行的代码处理流程
当开始一个try语句后,python会在当前程序的上下文中进行标记,这样当异常出现时就可以回到这里,try子句先执行,接下来发生什么依赖于执行时是否出现异常。
- 当try后面的语句执行出现异常,python就会调回try并执行第一个匹配该异常的except子句,异常处理完成,然后控制流通过整个try语句。
- 当try后面的语句执行出现异常,却没有匹配的except子句,异常将会被递交到上层的try,或者到程序的最上层(也就是结束程序,并打印出缺省的出错信息)。
- 当try子句执行没有异常,python将执行else后面的语句,然后控制流通过整个try语句。
实例
- 有异常出现被捕获的情况
1
2
3
4
5
6
7
8
9
10try:
print("开始计算")
result = 2/0
print("计算结果为:{0}".format(result))
except Exception as e:
print("除数不能为0")
else:
print("无异常出现")
finally:
print("done")
输出结果1
2
3开始计算
除数不能为0
done
根据输出结果可以看到,有异常出现的时候,先执行try
语句,遇到异常则停止执行下面的语句(print("计算结果为:{0}".format(result))
未执行),跳转至错误处理代码,也就是except
语句块,执行完except
后执行finally
语句块。不执行else
语句块。
- 无异常出现情况
1
2
3
4
5
6
7
8
9
10try:
print("开始计算")
result = 2/1
print("计算结果为:{0}".format(result))
except Exception as e:
print("除数不能为0")
else:
print("无异常出现")
finally:
print("done")
输出结果1
2
3
4开始计算
计算结果为:2.0
无异常出现
done
根据输出结果可以看到,无异常出现的时候先后执行了try
、else
和finally
语句块,未执行except
语句块。
在异常处理时else
和finally
语句块可以没有。
- raise抛出错误
1
2
3
4
5
6
7
8
9
10
11try:
print("开始计算")
result = 2/0
print("计算结果为:{0}".format(result))
except Exception as e:
print("除数不能为0")
raise e #添加raise语句抛出错误
else:
print("无异常出现")
finally:
print("done")
输出结果1
2
3
4
5
6
7开始计算
除数不能为0
done
Traceback (most recent call last):
File "<stdin>", line 7, in <module>
File "<stdin>", line 3, in <module>
ZeroDivisionError: division by zero
通过添加raise
抛出错误,我们可以看到错误类型为ZeroDivisionError
。
在python中内置了很多的错误类型,我们可以通过针对不同的错误类型,可以使用不同的except
语句处理。1
2
3
4
5
6
7
8
9
10
11
12
13
14try:
print("开始计算")
result = 2/int('a')
print("计算结果为:{0}".format(result))
except ZeroDivisionError as e:
print("除数不能为0")
raise e
except ValueError as e:
print("ValueError")
raise e
else:
print("无异常出现")
finally:
print("done")
输出结果1
2
3
4
5
6
7开始计算
ValueError
done
Traceback (most recent call last):
File "<stdin>", line 10, in <module>
File "<stdin>", line 3, in <module>
ValueError: invalid literal for int() with base 10: 'a'
此时执行try
语句块时,int()
函数抛出ValueError
异常,所以执行了第二个except
捕获对应异常信息。
前面我们在except
中直接使用Exception
,由于大部分的错误类型都是继承自该类型,所以可直接捕获其子类。
python中所有的错误都是从BaseException
类派生的,点击查看常见的错误类型和继承关系。
异常信息规范输出
在常见的前后端分离开发环境中,对于异常信息通常都是按照约定格式,返回json字符串,从而将异常信息记录下来。
下面是一个示例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import json
def log():
result = {}
try:
print(2/0)
except Exception as e:
result["msg"] = "Division can not be 0"
result["code"] = 250
result["data"] = [{"a": 1}, {"b": 2}]
finally:
return json.dumps(result) #字典转换为json串
if __name__ == '__main__':
print(log())
输出结果1
{"msg": "Division can not be 0", "code": 250, "data": [{"a": 1}, {"b": 2}]}