一、异常引入
1、异常概述
- 当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的异常,即常说的 Bug
2、异常演示
- 以 r 模式打开一个不存在的文件
f = open('linux.txt', 'r')
- 输出结果
Traceback (most recent call last):File "D:\系统默认\桌面\其他\Python\Python 基础入门\演示\pythonBasic\8.errorModulePackage\8-1.ErrorShow.py", line 1, in <module>f = open('linux.txt', 'r')
FileNotFoundError: [Errno 2] No such file or directory: 'linux.txt'
二、异常捕获
1、基本介绍
-
世界上没有完美的程序,任何程序在运行的过程中,都有可能出现异常,也就是出现 Bug,导致程序无法运行下去,我们要做的,不是力求程序完美运行,而是在力所能及的范围内,对可能出现的 Bug,进行提前准备、提前处理,这种行为称之为异常捕获
-
当程序遇到了 Bug,有两种情况,要么整个程序因为一个 Bug 停止运行,要没对 Bug 进行提醒,整个程序继续运行
-
捕获异常的作用在于:提前假设某处会出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段
2、捕获常规异常
(1)基本介绍
try:【可能发生异常的代码】
except:【捕获异常后执行的代码】
(2)基本使用
- 尝试以 r 模式打开文件,如果文件不存在,则以 w 模式打开
try:f = open('linux.txt', 'r')
except:f = open('linux.txt', 'w')
3、捕获指定异常
try:print(name)
except NameError as e:print('name 变量未定义异常')try:1 / 0
except NameError as e:print('发生了异常')
- 输出结果
Traceback (most recent call last):File "D:\系统默认\桌面\其他\Python\Python 基础入门\演示\pythonBasic\8.errorModulePackage\8-3.CatchNameError.py", line 8, in <module>1 / 0
name 变量未定义异常
-
如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常
-
一般 try 下方只放一行尝试执行的代码
4、捕获多个异常
- 当捕获多个异常时,可以把要捕获的异常类型,使用元组的方式进行书写到 except 后
try:1 / 0
except (NameError, ZeroDivisionError) as e:print('发生了异常')
5、捕获异常并输出描述信息
try:print(name)
except NameError as e:print(e)try:1 / 0
except ZeroDivisionError as e:print(e)
- 输出结果
name 'name' is not defined
division by zero
6、捕获所有异常
try:print(name)
except Exception as e:print(e)try:1 / 0
except Exception as e:print(e)
- 输出结果
name 'name' is not defined
division by zero
7、异常 else
- else 表示的是如果没有异常要执行的代码
try:print(1)
except Exception as e:print(e)
else:print('我是 else 1,是没有异常的时候执行的代码')try:print(name)
except Exception as e:print(e)
else:print('我是 else 2,是没有异常的时候执行的代码')
- 输出结果
1
我是 else 1,是没有异常的时候执行的代码
name 'name' is not defined
8、异常 finally
- finally 表示的是无论是否发生异常都要执行的代码,例如,关闭文件
try:print(1)
except Exception as e:print(e)
else:print('我是 else 1,是没有异常的时候执行的代码')
finally:print('我是 finally 1')try:print(name)
except Exception as e:print(e)
else:print('我是 else 2,是没有异常的时候执行的代码')
finally:print('我是 finally 2')
- 输出结果
1
我是 else 1,是没有异常的时候执行的代码
我是 finally 1
name 'name' is not defined
我是 finally 2
三、异常传递
1、基本介绍
- 异常是具有传递性的,当这个传递的异常没有(在各个函数中)被捕获时,程序就会报错
2、演示
-
当函数 fn1 中发生异常,并且没有捕获这个异常的时候,异常会传递到函数 fn2,当函数 fn2 也没有捕获这个异常的时候,异常会传递到函数 main
-
利用异常具有传递性的特点,当我们想要保证程序不会因为异常崩溃的时候,就可以在 main 函数中设置异常捕获,由于无论在整个程序哪里发生异常,最终都会传递到 main 函数中,这样就可以确保所有的异常都会被捕获
def fn1(): # 异常在 fn1() 中没有被捕获print("fn1 开始")1 / 0print("fn1 结束")def fn2(): # 异常在 fn2() 中没有被捕获print("fn2 开始")fn1()print("fn2 结束")def main(): # 异常在 main() 中被捕获try:print("main 开始")fn2()print("main 结束")except ZeroDivisionError as e:print(e)main()
- 输出结果
main 开始
fn2 开始
fn1 开始
division by zero