在Python里,程序出错时解释器会自动抛出内置异常,但有时我们需要根据业务逻辑主动提醒调用者出了问题,这时就要手动抛出异常。最常用的方式就是raise关键字,同时我们也能通过自定义异常让错误类型更明确。

一、raise关键字的基本用法
raise后面可以直接跟一个异常类的实例,也可以跟异常类本身。最简单的形式是抛出一个已有的内置异常:
# 直接抛出指定异常类型的实例
raise ValueError("年龄不能为负数")
# 也可以先创建异常再抛出
err = TypeError("类型不匹配")
raise err
当代码执行到raise语句时,当前函数会立刻停止,异常沿着调用栈向上传递,直到被try except捕获或者导致程序终止并打印追踪信息。
二、在捕获后重新抛出
有时我们想在except里做一点处理,再把这个异常抛出去,可以用单独的raise保留原堆栈:
try:
num = int("abc")
except ValueError:
print("转换失败,记录日志")
raise # 原样重新抛出,不丢失原始错误信息
三、为什么需要自定义异常
内置异常虽然多,但业务含义不够直观。比如用户余额不足、订单状态非法,用ValueError总显得含糊。自定义异常能清晰表达错误场景,也方便调用方针对性捕获。
四、如何定义并抛出自定义异常
自定义异常一般继承Exception或其子类,可以什么都不写,也可以扩展属性:
class BalanceNotEnoughError(Exception):
"""余额不足异常"""
def __init__(self, balance, need):
super().__init__(f"余额{balance}不足,需要{need}")
self.balance = balance
self.need = need
def pay(balance, cost):
if balance < cost:
# 手动抛出自定义异常
raise BalanceNotEnoughError(balance, cost)
return balance - cost
try:
pay(10, 50)
except BalanceNotEnoughError as e:
print(e)
print("当前余额:", e.balance)
自定义异常的使用建议
- 异常类名以Error结尾,符合Python惯例
- 只捕获你能合理处理的异常,不要笼统写except Exception
- 在模块顶部集中定义自定义异常,方便统一管理
五、常见注意点
在条件判断中手动抛异常时,要把raise放在真正违背约束的地方,避免正常流程也被中断。另外,raise后面如果是字符串而不是异常对象,在Python 3里会直接报TypeError,必须传异常实例或类。
手动抛出异常不是错误设计,而是让接口契约更清楚的手段。
通过上述方式,你就可以用raise灵活地抛出内置或自定义异常,让Python代码在异常场景下更可读、更好维护。