异常处理
什么是异常
异常是程序在执行过程中发生的错误事件,它会中断正常的程序流程。Python通过异常处理机制让你能够优雅地处理这些错误,而不是让程序崩溃。
# 没有异常处理的代码
result = 10 / 0 # 会抛出ZeroDivisionError
# 有异常处理的代码
try:
result = 10 / 0
except ZeroDivisionError:
print("不能除以零!")
try/except基本用法
try/except是异常处理的基本结构,它让你能够捕获并处理可能发生的错误。
# 捕获特定异常
try:
num = int(input("请输入一个数字: "))
result = 100 / num
print(f"结果是: {result}")
except ValueError:
print("输入的不是有效数字!")
except ZeroDivisionError:
print("不能除以零!")
捕获多种异常
你可以在一个except块中捕获多种异常,或者使用多个except块分别处理不同类型的异常。
# 在一个except块中捕获多种异常
try:
x = int(input("输入x: "))
y = int(input("输入y: "))
result = x / y
except (ValueError, ZeroDivisionError) as e:
print(f"发生错误: {e}")
# 使用多个except块
try:
data = [1, 2, 3]
print(data[10])
except IndexError:
print("索引越界!")
except Exception as e:
print(f"其他错误: {e}")
try/except/else/finally
完整的异常处理结构包含else和finally子句,它们各有特定用途。
try:
num = int(input("输入数字: "))
result = 100 / num
except ValueError:
print("输入无效!")
except ZeroDivisionError:
print("不能除以零!")
else:
# 只有在try块没有异常时才执行
print(f"计算结果: {result}")
finally:
# 无论是否有异常都会执行
print("程序执行完毕")
raise抛出异常
raise语句让你能够主动抛出异常,这在验证输入或实现自定义错误时非常有用。
def set_age(age):
if not isinstance(age, int):
raise TypeError("年龄必须是整数")
if age < 0 or age > 150:
raise ValueError("年龄必须在0到150之间")
return age
try:
set_age(-5)
except ValueError as e:
print(e) # 输出: 年龄必须在0到150之间
自定义异常
创建自定义异常类可以让你的代码更加清晰,错误信息更加有意义。
# 自定义异常类
class InsufficientFundsError(Exception):
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(f"余额不足: 当前余额{balance},需要{amount}")
class BankAccount:
def __init__(self, balance=0):
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise InsufficientFundsError(self.balance, amount)
self.balance -= amount
return self.balance
# 使用自定义异常
account = BankAccount(100)
try:
account.withdraw(150)
except InsufficientFundsError as e:
print(e) # 输出: 余额不足: 当前余额100,需要150
异常链与上下文
Python支持异常链,让你能够在处理异常时保留原始错误信息。
# 使用raise from创建异常链
try:
result = int("abc")
except ValueError as original:
raise RuntimeError("数据转换失败") from original
# 处理异常链
try:
try:
result = int("abc")
except ValueError as e:
raise RuntimeError("处理数据时出错") from e
except RuntimeError as e:
print(f"错误: {e}")
print(f"原始错误: {e.__cause__}")
最佳实践
- 只捕获你知道如何处理的异常,不要捕获所有异常
- 使用具体的异常类型,而不是通用的
Exception - 保持异常处理代码简洁,复杂逻辑应该提取到单独的函数中
- 使用自定义异常来表达业务逻辑中的特定错误情况
- 在
finally块中进行资源清理,如关闭文件、释放锁等 - 记录异常信息,便于调试和问题追踪
异常处理是编写健壮Python程序的关键技能,合理的异常处理能让程序更加稳定可靠。