Python 错误处理 完整通俗教程
·
程序运行时难免出错,比如用户输错数据、文件找不到、网络突然断开。错误处理能让程序:
- 不崩溃:遇到问题能稳住,给用户友好提示而不是直接闪退。
- 好维护:快速定位问题在哪,不用像猜谜一样排查。
- 更健壮:意外情况早有预案,比如重试连接或切换备用方案。
简单说就是:让程序像老司机,爆胎了还能安全靠边,而不是直接翻车。
一、什么是异常(错误)
程序正常运行时,遇到非法操作、数据错误、文件不存在、网络失败、索引越界等问题,会直接终止程序、抛出红色报错,这就是异常。错误处理作用:
- 不让程序直接崩溃闪退
- 捕获错误、打印友好提示
- 出错后可以兜底执行代码、释放资源
- 主动拦截非法数据,规范代码逻辑
二、核心语法:try /except
基础结构:
try:
# 有可能报错的代码,写在这里
可能出错的逻辑
except:
# 一旦 try 里代码报错,立刻执行这里
错误兜底逻辑
基础范例(无错误处理 vs 错误处理)
# 无错误处理:除数为0,程序直接崩溃
# a = 10 / 0
# 加错误处理:捕获异常,程序正常运行
try:
a = 10 / 0
except:
print("代码出错了,不能除以0")
三、捕获指定异常(重点推荐)
不建议直接写裸except,会隐藏所有 bug。指定捕获某一种错误,其他错误正常报错,方便调试。
try:
num = int("abc")
except ValueError:
print("类型错误:字符串无法转为数字")
四、获取错误详情 as e
可以接收异常对象,打印系统原始错误信息,方便排查问题。
try:
result = 20 / 0
except ZeroDivisionError as e:
# e 就是错误详情
print("捕获到错误:", e)
五、同时捕获多种异常
写法 1:多个异常写在一个括号内
try:
data = [1,2,3][5]
except (ZeroDivisionError, IndexError, ValueError) as e:
print("触发范围类错误:", e)
写法 2:分开捕获,不同错误不同处理
try:
f = open("test.txt", "r")
num = int("kkk")
except FileNotFoundError:
print("错误:文件不存在")
except ValueError:
print("错误:数据格式非法")
except Exception as e:
# Exception 是所有异常的父类,放在最后兜底
print("未知错误:", e)
六、else 分支:无报错才执行
try 代码完全正常、没有异常时,才会走 else 代码块。
try:
age = int("25")
except ValueError:
print("格式错误")
else:
print("转换成功,年龄为:", age)
七、finally 分支:无论对错必执行
不管代码报错与否,finally 里的代码100% 执行。核心用途:关闭文件、断开连接、释放内存、销毁资源。
f = None
try:
f = open("test.txt", "r", encoding="utf-8")
content = f.read()
except FileNotFoundError:
print("文件不存在")
finally:
# 无论是否报错,都关闭文件
if f:
f.close()
print("文件已强制关闭")
八、常用内置异常(开发高频)
日常写代码只需要熟记这些:
ValueError:数值 / 格式错误,字符串转数字失败ZeroDivisionError:除以零错误IndexError:列表 / 字符串索引越界KeyError:字典找不到 keyTypeError:数据类型不匹配FileNotFoundError:文件不存在AttributeError:对象没有这个属性 / 方法(类开发常用)
九、主动抛出异常 raise
不止捕获错误,还可以手动主动抛错。用来校验数据、限制传参,不符合规则直接拦截。
基础用法
def set_age(age):
if age < 0 or age > 150:
# 主动抛出指定异常
raise ValueError("年龄必须在0~150之间")
print("年龄设置成功:", age)
# 合法数据
set_age(20)
# 非法数据,主动报错
# set_age(-5)
十、自定义异常(结合前面 类 的知识点)
Python 允许自己写异常类,继承内置 Exception 父类,适合大型项目、自定义业务报错。完全复用之前学的 class 类语法。
# 自定义业务异常
class UserError(Exception):
# 继承系统异常父类
pass
class PasswordError(Exception):
pass
# 模拟登录校验
def login(username, pwd):
if not username:
raise UserError("用户名不能为空")
if len(pwd) < 6:
raise PasswordError("密码长度不能小于6位")
# 测试捕获自定义异常
try:
login("", "123")
except UserError as e:
print("账号错误:", e)
except PasswordError as e:
print("密码错误:", e)
十一、嵌套异常处理
复杂逻辑支持多层 try 嵌套,局部错误局部捕获,不影响整体流程。
try:
print("外层逻辑开始")
try:
1 / 0
except ZeroDivisionError:
print("内层:捕获除零错误")
except:
print("外层全局兜底")
十二、综合实战案例(整合全部知识点)
输入数字、除法计算、完整容错,贴近实际业务:
def calc_div():
try:
a = int(input("请输入第一个数字:"))
b = int(input("请输入第二个数字:"))
res = a / b
except ValueError:
print("错误:必须输入纯数字")
except ZeroDivisionError:
print("错误:第二个数字不能为0")
except Exception as e:
print("未知错误:", e)
else:
print("计算结果:", res)
finally:
print("计算流程结束")
calc_div()
十三、开发最佳实践(必看)
- 禁止无脑裸
except:,优先捕获指定异常,保留调试能力 - 兜底统一用
except Exception放在最后,不要滥用 - 资源操作(文件、数据库、网络)必须搭配
finally释放 - 业务校验用
raise主动抛错,规范入参 - 大型项目使用自定义异常类,区分系统错误和业务错误
- 不要用异常代替正常判断,能 if 判断的逻辑,优先用 if
快速知识点总结
try包裹高危代码,except捕获异常as e接收错误信息,方便定位问题else无报错执行,finally强制兜底执行raise手动抛出异常,用于数据校验- 自定义异常:新建类继承
Exception - 错误处理 + 前面学的类 / 接口,是项目稳定运行的核心组合
更多推荐



所有评论(0)