一、异常的概念
1、什么是错误
错误是指由于逻辑或语法等导入一个程序无法正常执行的问题
错误的特点
有些错误是无法预知的
2、什么是异常
异常是程序出错时标识的一种状态
当异常发生时,程序不会再向下执行,而转去调用此函数的地方待处理此错误并恢复为正常状态
异常的作用
用作信号,通知上层调用者有错误需要处理
二、try语句
1、try-except语句语法
语法
try:可能触发异常的语句
except 错误类型1 [as 变量1]:
异常处理语句1
except 错误类型2 [as 变量2]:
异常处理语句2
except (错误类型3, 错误类型4) [as 变量3]:
异常处理语句3
...
except:
异常处理语句other
else:
末发生异常语句
finally:
最终语句
作用
尝试捕获异常,将程序转为正常状态并继续执行
说明
a、as子句是用于绑定错误对象的变量,可以省略
b、except 子句可以有一个或多个,但至少要有一个
c、else 子句最多只能有一个,也可以省略
d、finally子句最多只能有一个,也可以省略
示例
def div_apple(n):
"""此示例用分苹果来示意捕捉异常"""
print("%d个苹果您想分给几个人?" % n)
s = input("请输入人数: ")
cnt = int(s) # <--此处可能触发ValueError类型的错误
result = n / cnt # <-- 此处可能会触发ZeroDivisionError类型的错误
print("每个人分了%d个苹果" % result)
try:
div_apple(10) # 此函数可能会触发错误,分苹果失败
print("分完苹果")
except ValueError:
print("分苹果失败,程序已捕获通知并转为正常状态")
except ZeroDivisionError:
print("没有人来,那苹果就拿来回吧!")
print("程序正常退出")
多个类型错误异常,处理的方式一样
try:
div_apple(10) # 此函数可能会触发错误,分苹果失败
print("分完苹果")
except (ValueError, ZeroDivisionError): # 多个类型错误异常, 处理的方式一样
print("苹果不分了")
print("程序正常退出")
当错误类型不匹配时,调用except : 在这里处理
try:
div_apple(10) # 此函数可能会触发错误,分苹果失败
print("分完苹果")
except ValueError:
print("苹果不分了")
except:
print("其它类型的错误已捕获!")
print("程序正常退出")
完整(as、else、finally)
try:
div_apple(10) # 此函数可能会触发错误,分苹果失败
print("分完苹果")
except ValueError:
print("苹果不分了")
except exception as e:
print("其它类型的错误已捕获!", e)
else:
# 此处语句只有在没有发生异常时才会执行
print("分苹果时没有发生异常")
finally:
# finally 子句中的内容在任何情况下都会被执行
print("我一定会执行的!!!!!")
print("程序正常退出")
2、try-finally 语句
语法
try:
可能触发异常的语句
finally:
一定要执行的最终语句
说明
a、finally 子句不可以省略
b、一定不存在except子句
作用
通常用try-finally语句来做触发异常时必须要处理的事情,无论异常是否发生,finally子句都会被执行
注:try-finally 语句不会改变程序的状态(正常/异常)状态
示例
def fry_egg():
print('打开天燃气....')
try:
count = int(input("请输入鸡蛋个数: "))
print("共煎了", count, '个鸡蛋')
finally:
print('关闭天燃气')
try:
fry_egg()
except ValueError:
pass
print("程序正常执行")
三、raise 语句
作用
触发一个错误,让程序进入异常状态
语法
raise 异常类型
或
raise 异常对象
示例
def make_exception(n):
# 假设n必须是0-100的整数
print("begin....")
# 触发ValueError类型的异常并进入异常状态
# raise 异常类型
if n > 100:
raise ValueError
# raise 异常对象
if n < 0:
raise ValueError("这是我自己定义的一个错误")
print("end")
value = int(input("请输入一个整数:"))
try:
make_exception(value)
print("make_exception调用结束")
except ValueError as e:
print("try里出现了值错误通知,已捕获!!!")
print("接收的异常通知是: ", e)
四、assert 语句(断言语句)
语法
assert 真值表达式,错误数据(通常是字符串)
作用
当真值表达式为False时,用错误数据创建一个 AssertionError 类型的错误,并进入异常状态
等同于:
if 真值表达式 == False:
raise AssertionError(错误数据)
示例
def get_score():
s = int(input("请输入学生成绩: "))
# 用assert语句来断言s是否在 0~100之间
assert 0 <= s <= 100, "用户输入的整数不在0~100之间"
return s
try:
score = get_score()
print("学生成绩为:", score)
except ValueError:
print("用户输入的成绩无法转化为整数")
except AssertionError as err:
print("发生了断言错误,原因是:", err)
五、with语句(高级)
语法
with 表达式1 [as 变量1],表达式2 [as 变量2], ...:
语句块
作用
使用于对资源进行访问的场合,确保使用过程中不管是否发生异常,都会执行必须的'清理'操作,并释放资源
如: 文件使用后自动关闭,线程中锁的自动获取和释放等
说明
a、执行表达式 用as 子句中的变量绑定生成的对象
b、with 语句并不会改变异常的状态,通常在最外层加try-except语句
示例
src_file = input("请输入源文件: ")
dst_file = input("请输入目标文件: ")
try:
with open(src_file, 'rb') as src:
# 准备打开别一个文件
with open(dst_file, 'wb') as dst:
# 开始读写文件
b = src.read()
dst.write(b)
except OSError:
print("复制失败")
六、综合
1、为什么要用异常处理机制
在程序调用层数较深时,向主调函数传递错误信息需要层层return返回比较麻烦,所以用异常处理机制来解决此类问题
2、异常小结
语句
try-except
捕获异常,偿试接收异常通知
try-finally
执行一定要执行的语句
raise
发送异常通知,将程序转为异常状态(进入异常流程)
assert
根据条件来触发AssertionError类型的异常
with IO操作