介绍
- 异常:就是程序运行过程中出现的错误,它会中断程序的正常执行流程。
- 作用:
- 保证数据、逻辑的正确性,避免程序执行混乱
- 在开发阶段,尽量发现更多的问题,尽早解决问题,保障程序正常执行
total = 20000
num = input("请输入取款金额: ")
print(f"您的银行卡余额为: {total - int(num)}")
print("请取出您的银行卡, 欢迎您下次光临")比如,在程序中,我们期望用户输入的取款金额是一个数字,如果用户输入数字,是没问题的,会将num字符串转为int类型。 但是如果用户输入的是 ABC 这样的非数字,那么此时转为int类型,程序就会报错,就会出现异常。【因此,这个异常是不是就是为了保证数据的正确性的】
异常的处理
处理异常并不是让异常消失,而是需要将异常捕获到,然后根据捕获到的异常的情况,按照我们自己的处理方式,处理完异常,程序继续执行。(编写程序时,做好预案,出现异常后,按照预案处理)
try:
可能出现异常的业务代码1
可能出现异常的业务代码2
...
except [异常类型1 as 变量名]:
出现异常1时的预案
except [异常类型2 as 变量名]:
出现异常2时的预案
except [异常类型3 as 变量名]:
出现异常3时的预案
except [异常类型4 as 变量名]:
出现异常4时的预案
...程序正常运行,except代码块中的代码不会运行。一旦程序运行出现错误,就会执行except中的异常处理逻辑,给用户提示出对应的错误信息。
可以使用多个except捕获多种不同类型的异常的。如果捕获了多种异常,程序运行出现异常后,会从上往下匹配,直到找到能处理该异常的except代码块,如果全部都匹配不到,异常就会直接抛出来,直接报错。
"""
- 异常:就是程序运行过程中出现的错误,它会中断程序的正常执行流程。
- 作用:
- 保证数据、逻辑的正确性,避免程序执行混乱
- 在开发阶段,尽量发现更多的问题,尽早解决问题,保障程序正常执行
- 处理方式:
try: #try中放可能出现异常的代码
可能出现异常的业务代码1
可能出现异常的业务代码2
...
except [异常类型 as 变量名]: # 处理异常的代码块,except可以有多个,分别处理不同类型的异常
出现异常时的预案
except [异常类型 as 变量名]: # 处理异常的代码块,except可以有多个,分别处理不同类型的异常
出现异常时的预案
- 快捷键:选中要放到try中的代码,ctrl+alt+t--->选择try/except
"""
try:
a = int(input("请输入第一个数:"))
b = int(input("请输入第二个数:"))
sum = a+b
c=a/b
print(f"两个数之和:{sum}")
except ValueError as err: # err是变量名,用来接收ValueError类型的异常,可以通过err变量获取异常的原因记录到文件中
# print(err.args,type(err.args)) #err.args元组类型,存储异常原因,异常原因后期可以存到数据库、文件中,让开发人员查看
print("请输入数字!")
except ZeroDivisionError as err:
print("除数不能为0!")
# 当然,在实际的开发中,一般会直接选择except Exception这个方案捕获错误,因为其他的类型太具体了,有些错误我们是没办法提前知道具体的错误类型的
except Exception as err:
print("程序开小差了,请稍后重试!")
finally:
print("无论是否发生异常,都会执行的代码块")
print("程序执行结束了...")如果 try 代码块中的代码运行出现异常,会从上往下匹配:先匹配ValueError类型,如果匹配上了,就执行except中的逻辑; 如果没有匹配上,继续往下匹配,匹配ZeroDivisionError ,如果匹配成功,就执行except中的逻辑;否则,会继续往下匹配。 而最后一个except,捕获的是Exception,这个是我们常见的这些错误的父类,如果前面的都没有匹配上,这个就会兜底。
异常传递
异常传递就是异常在函数调用中层层上报的过程,直到有人处理它,或者程序崩溃。
def fun1():
print("fun1开始")
fun2()
print("fun1结束")
def fun2():
print("fun2开始")
fun3()
print("fun2结束")
def fun3():
print("fun3开始")
a = int(input("请输入第一个数:"))
b = int(input("请输入第二个数:"))
sum = a+b
print(f"两个数之和:{sum}")
print("fun3结束")
if __name__ == "__main__":
try:
fun1() #快捷键:选中要放到try中的代码,ctrl+alt+t--->选择try/except
except Exception as e:
print("服务器正在升级,么么哒!")程序运行时,调用的是fun1函数,fun1中调用了fun2,fun2中调用了fun3,如果fun3函数体的逻辑运行出现异常,异常未被捕获处理,则会顺着调用链路,一层一层的往上抛 (fun3 ---> fun2 ---> fun1 ---> 入口)。
案例优化
学习了异常处理方案后,我们再来对我们的案例程序进行优化。由于 LibrarySystem 中的 run 方法是图书管理系统运行的入口,因此最简单的异常处理方案,就是在入口处,我们捕获所有的异常,然后给出用户提示就可以了 。(此处请参考面向对象部分的图书管理系统的代码)
# -------------------启动程序--------------------
if __name__ == "__main__":
# ls = LibrarySystem()
# ls.run()
try: #快捷键:选中要放到try中的代码,ctrl+alt+t--->选择try/except
LibrarySystem().run() # 创建LibrarySystem对象立马调用run()方法。由上面两行代码合并而来。
except Exception as e:
print(e.args) #给开发人员看
print("服务器正在升级,么么哒!") #返回到页面,给用户看