Python 内置异常可以处理很多通用错误,但真实项目经常会遇到业务规则错误。例如“库存不足”不是语法错误,也不是类型错误,而是一条业务规则被违反。
定义异常类
自定义异常(custom exception)通常继承 Exception。简单异常类可以先只写 pass,在 raise 时传入具体信息。名称应清楚表达错误含义,让调用者无需解析文字就能识别错误类别。
class OutOfStockError(Exception):
pass
raise OutOfStockError("Notebook is out of stock.")知识测验
题目
自定义异常通常继承哪个类?
库存案例
ValueError 表示购买数量本身不合理;OutOfStockError 表示数量虽然合理,但当前库存无法满足。不同异常表达不同层次的问题。
class OutOfStockError(Exception):
pass
class Product:
def __init__(self, name, stock):
self.name = name
self.stock = stock
def purchase(self, quantity):
if quantity <= 0:
raise ValueError("Quantity must be greater than 0.")
if quantity > self.stock:
raise OutOfStockError("%s is out of stock." % self.name)
self.stock -= quantity
product = Product("Notebook", 5)
try:
product.purchase(3)
print("Remaining stock:", product.stock)
product.purchase(4)
except OutOfStockError as error:
print("Purchase failed:", error)Remaining stock: 2
Purchase failed: Notebook is out of stock.知识测验
题目
OutOfStockError 比普通 Exception 更有价值的原因是什么?
为什么要自定义异常
自定义异常的价值是语义。捕获 OutOfStockError 后,界面可以提供“补货”或“更换商品”;捕获 ValueError 时,则应要求用户修改数量。调用方也可以分别记录、重试或向上继续抛出这些错误。
| 错误 | 含义 | 可能处理 |
|---|---|---|
ValueError | 参数无效 | 要求重新输入 |
OutOfStockError | 库存不足 | 补货或换商品 |
知识测验
题目
库存案例中,哪项分类最合理?
动手练习
定义 IllegalTriangleError
- 定义继承 Exception 的 IllegalTriangleError。
- Triangle.__init__ 对非正数边抛出 ValueError。
- 三边不满足任意两边之和大于第三边时,抛出 IllegalTriangleError。
- 主程序分别捕获两个异常,并输出不同提示。