Python异常处理
一、什么是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捕获异常,如我接住你扔出来的错误,不让程序崩溃。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)