day17 课程(异常 & 异常类型 & 捕获异常 & 异常描述信息 & 异常else|finally &异常传递 & 自定义异常)
课程:https://www.bilibili.com/video/BV1o4411M71o?spm_id_from=333.788.videopod.episodes&p=316
17.1 了解异常
17.1.1 目标
了解异常
捕获异常
异常的else
异常的finally
异常的传递
自定义异常
17.1.2 了解异常
当检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”,通过当遇到异常,执行遇到异常后的其他代码的方式继续向下执行代码
例如:以 r 方式打开一个不存在的文件
# 打开不存在的文件 报错: FileNotFoundError open("1.txt", "r") print("hello world") # 上面报错后, 下面的代码没有执行 ------------------------------------------------ 执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day17\01.了解异常.py Traceback (most recent call last): File "D:\Pycharm\code\day17\01.了解异常.py", line 3, in <module> open("1.txt", "r") ~~~~^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: '1.txt' Process finished with exit code 1
17.2 体验异常
17.2.1 语法
# 语法 try: 可能发生错误的代码 except: 如果出现异常执行的代码
17.2.2 快速体验
# 需求: 尝试以 r 模式打开文件, 如果文件不存在, 则以 w 方式打开 try: # 可能发生错误 f = open("1.txt", "r") # 未发生错误, 且创建了 1.txt 文件 except: # 遇到错误执行 f = open("1.txt", "w")
17.3 了解异常类型
# NameError # print(num) # 报错: NameError: name 'num' is not defined. Did you mean: 'sum'? # ZeroDivisionError # print(1/0) # 报错: ZeroDivisionError: division by zero
17.4 捕获指定异常类型
17.4.1 语法
# 语法 try: 可能发生错误的代码 except 异常类型: # 捕获某个异常类型 如果捕获到该异常类型执行的代码
17.4.2 快速体验
try: # 尝试执行 try print(num) except NameError: # 上面 try 执行的代码发生错误, 捕获是否是 NameError, 如果是, 则执行下方缩进代码 print("--名称错误--") ------------------------------------------------ 执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day17\04.捕获指定异常类型.py --名称错误-- Process finished with exit code 0
17.4.3 快速体验
try: # 尝试执行 try print(1/0) except NameError: # 上面 try 执行的代码发成错误, 捕获是否是 NameError, 如果不是, 则报原异常 print("--名称错误--") ------------------------------------------------ 执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day17\04.捕获指定异常类型.py Traceback (most recent call last): File "D:\Pycharm\code\day17\04.捕获指定异常类型.py", line 11, in <module> print(1/0) ~^~ ZeroDivisionError: division by zero Process finished with exit code 1
注意:1.如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常
2.一般 try 下方只放一行尝试执行的代码
17.5 捕获多个指定异常类型
不确定异常的类型,需要捕获多个异常时,可以把要捕获的异常类型的名字,放到 except 后,并使用元组的方式进行书写
try: print(1/0) except (NameError, ZeroDivisionError): # 多个异常的 以元组的方式书写 print("--有异常--") ------------------------------------------------ 执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day17\05.捕获多个指定异常类型.py --有异常-- Process finished with exit code 0
17.6 捕获异常描述信息
NameError, ZeroDivisionError 只是广义上的报错,没有提供具体错误信息的描述
try: print(1/0) except (NameError, ZeroDivisionError) as result: # 捕获异常的描述信息, 用变量 result 接收 print(result) # 打印异常信息 ------------------------------------------------ 执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day17\06.捕获异常描述信息.py division by zero Process finished with exit code 0
17.7 捕获所有异常
Exception 是所有程序异常类的父类,当不确定异常类型时,使用 Exception 可以接收所有异常类型
try: print(num) except Exception as e: # 可以接收异常类型 NameError print(e) try: print(1/0) except Exception as e: # 也可以接收异常类型 ZeroDivisionError print(e) ------------------------------------------------ 执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day17\07.捕获所有异常.py name 'num' is not defined division by zero Process finished with exit code 0
17.8 异常的 else
else 表示的是如果没有异常要执行的代码
try: print(1) # 没有异常 except Exception as e: print(e) else: print("我是 else, 是没有异常的时候执行的代码") # 执行 try: print(num) # 有异常报错 except Exception as e: print(e) else: print("我是 else, 是没有异常的时候执行的代码") # 不执行 ------------------------------------------------ 执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe "D:\Pycharm\code\day17\08.异常的 else.py" 1 我是 else, 是没有异常的时候执行的代码 name 'num' is not defined Process finished with exit code 0
17.9 异常的 finally
finally 表示的是无论是否异常都要执行的代码,例如关闭文件
# 当存在 1.txt ,不存在 2.txt 文件时, 执行下面代码 try: f1 = open('1.txt', "r") # 有 1.txt 执行成功 except Exception as e: f1 = open('1.txt', "w") # 有 1.txt 无报错, 不执行 else: print("else 执行么?") # 程序无异常, 执行 finally: print("finally 执行么?") # 无论程序正常还是异常, 都执行 f1.close() try: f2 = open('2.txt', "r") # 无 2.txt 执行失败 except Exception as e: f2 = open('2.txt', "w") # 执行 else: print("else 执行么?") # try 执行不成功, 不执行 finally: print("finally 执行么?") # 无论程序正常还是异常, 都执行 f2.close() ------------------------------------------------ 执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe "D:\Pycharm\code\day17\09.异常的 finally.py" else 执行么? finally 执行么? finally 执行么? Process finished with exit code 0
17.10 扩展命令提示符运行py文件
print("ok") ------------------------------------------------ 执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day17\10.扩展命令提示符运行py文件.py ok Process finished with exit code 0


注意:以上是 Python 代码的另一种执行方式
17.11 异常传递的思路分析
需求:
1.尝试只读方式打开 test.txt 文件,如果文件存在则读取文件内容,文件不存在则提示用户既可
2.读取内容要求:尝试循环读取内容,读取过程中如果检测到用户意外终止程序,则 except 捕获异常并提示用户
异常语句嵌套书写
17.12 异常传递的代码实现
import time # 1 导入时间模块, 下一节会学到 try: f = open("test.txt", "r") # 2.1 尝试打开文件 try: while True: content = f.readline() if len(content) == 0: # 3.1 按行循环读取文件内容, 读取不出来结束循环 break time.sleep(2) # 3.2 利用时间差, 可以制造文件打开突然关闭的情况 print(content) except : # 3.3 如果在读取文件的过程中,产生了异常, 可以捕获异常 print("意外终止了读取数据") finally: f.close() # 3.4 无论怎么样都要关闭文件 print("关闭文件") except Exception as e: print( f"{e} 存在报错 ") # 2.2 打不开时文件捕获异常
1.当不存在 test.txt 文件时

2.当存在 test.txt 文件时,使用 Ctrl + c 终端程序
aaaaa
bbbbb
ccccc
ddddd
eeeee

17.13 自定义异常的作用
在 Python 中,抛出自定义异常的语句为 raise 异常类对象
将不满足程序逻辑要求的代码捕获异常、抛出异常
17.14 自定义异常思路分析
需求:密码长度不足,则报异常(用户输入密码,如果输入的长度不足 3 位,即抛出自定义异常,并捕获该异常)
思路分析:
1.自定义异常类,异常类继承 Exception
2.抛出异常
3.捕获异常
17.15 自定义异常代码实现之异常类
# 1.自定义异常类 class ShortInputError(Exception): # 继承异常的父类 def __init__(self, length, min_length): # 魔法方法, 初始化执行 self.length = length self.min_length = min_length def __str__(self): # 魔法方法, 抛出异常的描述信息 return f"您输入的密码位数为 {self.length}, 输入最小密码位数为 {self.min_length}"
17.16 自定义异常代码实现之捕获异常
# 1.自定义异常类 class ShortInputError(Exception): # 继承异常的父类 def __init__(self, length, min_length): # 魔法方法, 初始化执行 self.length = length self.min_length = min_length def __str__(self): # 魔法方法, 抛出异常的描述信息 return f"您输入的密码位数为 {self.length}, 输入最小密码位数为 {self.min_length}" def main(): # 2.抛出异常 try: password = input("请输入密码: ") if len(password) < 3: # 判断位数是否小于 3,小于 3 才调用异常类, 大于 3 执行 else 代码 raise ShortInputError(len(password), 3) # raise 抛出异常类对象抛出的异常描述信息 # 3.捕获异常 except Exception as e: # 捕获异常类 print(e) else: # 没有异常, 执行的代码 print("密码已经输入完成") main() # 主函数的调用 ------------------------------------------------ 第一次执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day17\12.自定义异常.py 请输入密码: 1 您输入的密码位数为 1, 输入最小密码位数为 3 Process finished with exit code 0 ------------------------------------------------ 第二次执行后 C:\Users\马俊南\AppData\Local\Microsoft\WindowsApps\python3.13.exe D:\Pycharm\code\day17\12.自定义异常.py 请输入密码: 12345 密码已经输入完成 Process finished with exit code 0
17.17 异常总结
1.异常语法
try: 可能发生异常的代码 except: 如果出现异常执行的代码 else: 没有异常执行的代码 finally: 无论是否有异常都要执行的代码
2.捕获异常
try: 可能发生异常的代码 except (异常类型1, 异常类型2, 异常类型3, ...): 代码 try: 可能发生异常的代码 except (异常类型1, 异常类型2, 异常类型3, ...) as e: 代码
3.自定义异常
# 1.自定义异常类 class 异常类类名(Exception): 代码 # 设置抛出异常的描述信息 def __str__(self): return ... try: # 2.抛出异常 可能发生异常的代码 raise 异常类类名() # 3.捕获异常 except Exception as e: print(e)
———————————————————————————————————————————————————————————————————————————
无敌小马爱学习
浙公网安备 33010602011771号