Python异常处理笔记

try / except

基本语法

1
2
3
4
try:
# 可能发生异常的代码
except [ValueError/KeyError/...]:
# 发生异常时执行的代码

如果 except 没有指定捕捉哪种异常,则会捕捉所有异常。

示例

1
2
3
4
5
try:
number = int(input("请输入一个整数:"))
print(f"你输入的数字是:{number}")
except ValueError:
print("输入错误,请输入整数")

except Exception as error

使用 as 可以获取异常对象。

1
2
3
4
5
try:
number = int("abc")

except ValueError as error:
print(f"错误信息:{error}")

输出:

1
错误信息:invalid literal for int() with base 10: 'abc'

还可以使用:

1
2
3
4
5
6
try:
number = int("abc")

except Exception as error:
print(type(error).__name__)
print(error)

输出:

1
2
ValueError
invalid literal for int() with base 10: 'abc'

Exception 是大多数常见应用异常的基类。

因此:

1
except Exception as error:

可以捕获大多数常见异常。

但不建议所有程序都直接使用它,因为这样可能掩盖原本应该修复的程序错误。

推荐:优先捕获明确知道如何处理的异常类型。

常见异常类型

ValueError

输入转换错误,比如字母转换数字等

1
2
number = int("abc")
# abc转换成int型失败,此时就会抛出ValueError

ZeroDivisionError

除0错误,在除法中,除数不能为0

1
2
3
4
result = 10 / 2
# 结果为5
result = 10 / 0
# 除法中除数不能为0,此时会抛出ZeroDivisionError

KeyError

字典查询错误,访问字典中不存在的key时异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
students = {
"Tom": 80,
"Jack": 90,
"Mary": 75,
"Alice": 95
}

students["Tom"]
# 取得字典中Key值为Tom的Value值,即为80
students["David"]
# 意图为取得字典中Key值为David的Value值,但字典中不存在Key值为David的项,此时会抛出KeyError
# 另
students.get("David")
# 此时使用字典内部的get方法来访问,内部方法会进行检查,如果Key值不存在则会返回默认值None,而非抛出KeyError

IndexError

列表下标越界错误,访问下标超过列表最大下标时异常

1
2
3
4
5
6
numbers = [10, 20, 30, 40, 50]
# 有五个元素的列表,下标最大值为4
numbers[4]
# 取下标为4的元素,即50
numbers[5]
# 最大下标为4,5为越界,此时会抛出IndexError

其余常见异常类型

异常类型 说明 示例
TypeError 数据类型不符合要求 "10" + 5
NameError 使用未定义的变量 print(x)
FileNotFoundError 文件不存在 open("missing.txt")
PermissionError 文件或资源访问权限不足 无权限时写入文件
AttributeError 对象没有指定属性或方法 "abc".append(1)
ImportError 导入模块或对象失败 导入不存在的模块成员

else / finally

语法

1
2
3
4
5
6
7
8
try:
# 可能发生异常的代码
except:
# 发生异常时执行的代码
else:
# 未发生异常时执行的代码
finally:
# 无论如何都会执行

示例

1
2
3
4
5
6
7
8
try:
number = int(input("请输入一个整数:"))
except ValueError:
print("输入错误,请输入整数")
else:
print(f"你输入的数字是:{number}")
finally:
print("程序结束")

raise:主动抛出异常

使用 raise,可以根据自己的业务规则主动抛出异常。

语法

1
raise 异常类型("错误信息")

示例:检查年龄

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def check_age(age):
if age < 0 or age > 150:
raise ValueError("年龄必须在 0~150 之间")

return age


try:
age = int(input("请输入年龄:"))
check_age(age)

except ValueError as error:
print(f"错误:{error}")

else:
print("年龄合法")

例如输入 200:

1
错误:年龄必须在 0~150 之间

raise 和 print 的区别

1
print("年龄错误")

只会输出文字,函数仍可能继续执行。

1
raise ValueError("年龄错误")

会立即抛出异常,中断当前正常执行流程,并交给相应的异常处理代码。

函数中的异常传播

函数中发生异常时,如果函数内部没有捕获,异常会传播给调用者。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def check_score(score):
if score < 0 or score > 100:
raise ValueError("成绩超出范围")

return score

def add_student(score):
return check_score(score)

try:
add_student(120)

except ValueError as error:
print(error)

执行过程:

1
2
3
4
5
6
7
8
9
add_student(120)
↓
check_score(120)
↓
raise ValueError
↓
返回调用位置,异常继续传播
↓
外层 except 捕获

这就是异常传播(Exception Propagation)。

函数不一定需要自己处理所有异常,可以交给上层调用者决定如何处理。


Python异常处理笔记
https://umeshu.cn/2021/04/15/Python异常处理笔记/
作者
IchiharaYuuko
发布于
2021年4月15日
许可协议