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

image

image

注意:以上是 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 文件时

image

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

aaaaa
bbbbb
ccccc
ddddd
eeeee

image

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)

———————————————————————————————————————————————————————————————————————————

                                                                                                                         无敌小马爱学习

posted on 2025-10-05 17:04  马俊南  阅读(17)  评论(0)    收藏  举报