(从基础、规范写法、常用异常、自定义异常、实操避坑 全整理,适配你的代码习惯)
一、异常核心基础概念
- 什么是异常
代码运行时出现的错误、逻辑非法、参数不合法等,导致程序强制终止的报错,就是异常。
- 主动抛出异常关键字
只有 raise是 Python 主动抛异常的关键字。
- 两种报错本质区别
- 写法:raise "错误信息"
❌ 非法写法,不是业务异常,是 Python 语法报错:TypeError: exceptions must derive from BaseException
- 写法:Exception("错误信息")
✅ 标准规范,主动抛出业务异常,可被正常捕获、识别。
二、主动抛出异常 标准写法
1. 万能通用写法(日常开发首选)
不知道该用什么具体异常类型时,统一用顶层父类 Exception,全覆盖、不报错、好维护。
# 万能格式
raise Exception("自定义错误提示文本")
2. 规范细分内置异常(追求严谨时使用)
内置异常是 Python 自带分类,对应不同错误场景:
- AttributeError:属性不存在(适配你的 Config 配置类)
- ValueError:数值 / 参数非法
- KeyError:字典键不存在
- TypeError:数据类型错误
示例:
# 属性不存在专用
raise AttributeError("配置类无此属性")
# 数值错误专用
raise ValueError("年龄超出合法范围")
三、异常捕获基础 try...except
作用:拦截异常,防止程序崩溃,优雅处理错误。
try:
# 可能出错的代码
Config.set_attr("test", 123)
except Exception as e:
# 捕获异常并打印信息
print("执行失败:", e)
四、异常的传递与复用
-
重新抛出原有异常
try:
1 / 0except:
raise # 原样抛出上层异常,不修改信息 -
异常链式改写(极少用,了解即可)
五、自定义异常类(重点理解)
1. 核心理解
- 所有异常最终都继承自 BaseException;
- 自定义异常,只需要继承 Python 内置 Exception类;
- 作用:区分项目业务错误、系统错误,让报错分类更清晰,方便后期排查。
2. 自定义异常 基础语法
# 自定义业务异常基类
class BusinessError(Exception):
"""项目所有业务异常的父类"""
pass
# 细分场景异常
class ConfigAttrError(BusinessError):
"""配置类属性不存在异常"""
pass
class ParamError(BusinessError):
"""参数非法异常"""
pass
3. 自定义异常 实战使用
class Config:
@classmethod
def set_attr(cls, name, value):
if not hasattr(cls, name):
# 抛自定义异常
raise ConfigAttrError(f"配置项【{name}】不存在")
4. 自定义异常进阶(自定义错误信息)
class ConfigAttrError(Exception):
def __init__(self, msg: str):
self.msg = msg
super().__init__(self.msg)
# 使用
raise ConfigAttrError("禁止修改私有配置属性")
5. 自定义异常的价值
-
区分系统异常 和 自己项目业务异常;
-
捕获时可以精准拦截:
try:
Config.set_attr("xxx", 1)except ConfigAttrError:
# 只处理配置错误 print("配置校验失败")except Exception:
# 处理其他所有错误 print("系统未知错误") -
大型项目、SDK、库开发(如你的 LhPyQt5)必备,代码更规范。
六、结合你代码的实操标准示例
优化后 Config 配置类异常写法
# 自定义配置专属异常
class ConfigError(Exception):
pass
class Config:
is_generate_manager_account = False
@classmethod
def set_attr(cls, name: str, value):
if not hasattr(cls, name):
# 规范抛异常
raise ConfigError(f"当前配置类不存在属性:{name}")
setattr(cls, name, value)
七、关键避坑总结
- ❌ 禁止:raise "文字"
- ✅ 强制:raise 异常类(提示文字)
- 日常开发:优先 raise Exception("提示") 够用
- 精细化开发:使用对应内置异常 / 自定义异常
- 异常不要滥用:正常业务逻辑不要靠异常控制,只用于「非法、错误场景」
八、极简背诵口诀
- 抛异常必带异常类,不能直接抛字符串;
- 通用报错用 Exception,细分场景用内置异常;
- 自定义异常继承 Exception,用于业务分类;
- 异常用来兜底防崩溃,不用来替代正常判断。