一、什么是Python异常

1、定义

异常是 Python 程序运行期间检测到的非正常情况或错误事件,当程序无法按照正常逻辑继续执行时,会主动抛出异常对象,中断程序默认执行流程。

2、核心特点

(1)异常属于运行时错误,不是语法错误;语法错误在代码解析阶段就无法运行,异常是语法合法、执行过程中触发。
(2)异常发生后,若不进行捕获处理,程序会立即终止,并打印错误堆栈信息。

二、异常演示

例如:除数为0异常

print(10/0)

抛出ZeroDivisionError异常
在这里插入图片描述

三、为什么要做异常处理

  • 防止程序直接崩溃终止
    程序运行时一旦出现异常,若无异常处理,会直接中断执行、退出程序,后续所有代码都无法运行。
  • 提高程序健壮性与容错能力
    程序运行中会遇到不可预知的外部或数据问题:用户输入非法数据、文件不存在或路径错误、列表索引越界、字典键不存在等,异常处理可以对这些意外情况做兜底逻辑,让程序从容应对错误,而不是直接报错闪退。
  • 自定义友好错误提示
    系统默认的异常报错信息专业、晦涩,普通用户看不懂。通过捕获异常,自定义异常提示,可以屏蔽底层英文报错,输出通俗易懂的中文提示,提升交互体验。
  • 保证关键代码必须执行
    通过finally结构,无论是否发生异常,都能确保文件关闭、断开数据库连接、释放资源等,finally结构中的代码一定执行,避免资源泄漏。
  • 规范业务逻辑,主动抛出错
    可以用raise自定义抛出异常,对不符合业务规则的数据进行校验拦截,让程序逻辑更严谨规范。

四、常见Python异常

异常名称 中文名称 定义 错误场景
NameError 变量或名称未定义错误 使用了没有定义的变量 如num没有定义就直接打印print(num)
SyntaxError 语法错误 代码语法错误(不符合Python原则) if a>b,没有写冒号
IndexError 索引超出范围错误 索引或下标超过了指定范围 如列表lst=[1,2,3],打印print(lst[3]),下标最大是2
ZeroDivisionError 除零错误 除数为0 print(5/0)
KeyError 字典键不存在错误 字典中没有这个键 如字典info={"name":"张三"},打印print(info["age"]),age不存在
AttributeError 属性或方法不存在错误 对象没有这个属性 如字符串调用列表的append方法
ValueError 值类型或格式错误 传入的值不对(类型对但是内容无效) int("abc"),字符串不能转整型
TypeError 类型错误 类型不匹配 print(1+"2"),数字与字符串不能相加
ImportError 模块导入错误 导入模块失败(路径或模块名错误) import pandas123,模块名不存在
IndentationError 缩进错误 缩进错误(代码没对齐) 如python通常是四个缩进,只有两个缩进时抛异常

五、捕获异常

语法

try:
	# 尝试执行这段代码
    可能触发异常的代码块
except [异常类型 as 变名]:
	# 捕获异常后,执行这里的逻辑
    异常发生时执行的代码块
else:
	# 没有发生异常才执行这里
    无异常时执行的代码块
finally:
	# 不管有没有异常,最后都执行执行
    无论是否异常都执行的代码块

1、捕获所有异常

Exception 捕获所有的非语法错误
例如:

try:
    num = int(input("请输入一个数字:"))
except Exception:
    print(f"输入错误!请输入纯数字")

用户输入是字符串 aaa 时,抛出异常
在这里插入图片描述

2、捕获指定异常

  • 捕获单一异常
    例如:捕获值错误
try:
    num = int(input("请输入一个数字:"))
except ValueError:
    print("传入值错误,请输入纯数字")

在这里插入图片描述

  • 捕获多个异常
    捕获多个异常时同一逻辑处理,用元组指定多种异常,触发任意一种都执行相同处理。
    例如:捕获值错误和除零错误
try:
    num = int(input("请输入一个数字:"))
    print(5/0)
# 用元组同时捕获两种异常:值错误、除零错误
except (ValueError,ZeroDivisionError):
    print("发生错误!可能输入不对或除零错误")
用户输入数字,实际触发 ZeroDivisionError

在这里插入图片描述

用户输入字母,实际触发 ValueError

在这里插入图片描述

  • 分类型捕获:不同类型不同处理
    分类型捕获,是指在代码中通过多个独立的 except 分支,分别捕获不同类型的异常,并为每种异常编写专属的处理逻辑,能精准定位问题,给用户更明确、友好的反馈。
    例如:捕获值错误和变量未定义错误
try:
    num = int(input("请输入一个数字:"))
    print(num1)
except ValueError:
    print("输入错误!请输入纯数字")
except NameError:
    print("输入错误!使用没有定义的变量")
用户输入数字是,触发 NameError

在这里插入图片描述
用户输入数字是,触发 NameError
在这里插入图片描述

3、捕获异常描述信息

在 Python 中,用 as e 获取异常对象,打印具体错误原因,便于定位问题。
例如:

try:
    print(10/0)
except Exception as e:
    print(f"错误原因;{e}")

在这里插入图片描述

六、else用法

在 Python 异常处理中,else 是 try-except 结构的可选分支,它的核心作用是:当 try 代码块中没有发生任何异常时,才会执行 else 里的代码。
例如:

try:
    num = int(input("请输入一个数字:"))
except Exception as e:
    print(f"错误类型:{e}")
else:
    print(f"输入正确!你输入的数字是:{num}") 
用户输入正确(无异常,执行 else)

在这里插入图片描述

七、finally用法

在 Python 异常处理中,finally 是 try-except 结构的收尾分支,它的核心特性是:无论 try 代码块中是否发生异常,finally 里的代码都会被执行。常用于释放资源,如打开文件后,不管操作是否成功,最后都要关闭文件。
例如:

print("打开文件...")
try:
    print("文件操作")
except Exception as e:
    print(e)
finally:
    print("关闭文件...")
       

八、抛出自定义异常

1、定义

Python 内置了很多异常(如 ValueError、IndexError),但当这些通用异常无法精准描述你的业务错误时(比如 “年龄不能为负数”“密码长度不足”),就需要自定义异常类。
在代码中,通过raise关键字主动触发我们定义的异常,让程序按预期流程跳转到异常处理逻辑,而不是直接崩溃。

2、实现

自定义异常实现步骤:

  • 步骤1:创建异常对象
    语法:异常类型(异常具体描述信息)
  • 步骤2:用raise语句抛出异常对象
    语法:raise 异常对象

3、案例

例如:模拟银行取款。

# 需求:模拟银行取款场景
# 取款金额超出余额抛出余额不足异常,账户账号冻结抛出冻结异常

# 余额 1000
balance = 1000
# 账户状态,是否冻结 (False 没有冻结,True 冻结)
is_frozen = False

#实现一个功能的代码 ==> 函数
def bank(amount):
    global balance
    # 抛出异常
    # 先判断账户是否冻结
    if is_frozen:
        # 账户冻结 ==> 抛出异常
        raise Exception("账户冻结")
    # 再判断余额是否充足:余额 < 取款金额,余额不足 ==> 抛出异常
    if balance < amount:
        raise Exception(f"余额不足!当前余额:{balance}")
     # 取款:余额 = 余额-取款金额
    balance -= amount
    print(f"当前余额:{balance}")

# 捕获异常
try:
    bank(1500)
except Exception as e:
    print(e)

当取款金额1500大于余额是抛出异常,并且捕获到异常
在这里插入图片描述

注意:raise 是主动抛出异常,如我发现了错误,我把错误扔出去,try/except捕获异常,如我接住你扔出来的错误,不让程序崩溃。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐