Python 的异常处理机制是构建健壮程序的核心工具,通过 try-except
结构实现优雅的错误管理。以下是系统化指南:
一、基础异常处理结构
try:
# 可能出错的代码
result = 10 / 0
except ZeroDivisionError:
# 异常处理逻辑
print("错误:除数不能为零!")
二、异常处理进阶用法
1. 捕获多个异常类型
try:
# 可能引发多种异常的代码
with open("data.txt") as f:
data = f.read()
except (FileNotFoundError, UnicodeDecodeError) as e:
print(f"文件处理失败: {str(e)}")
2. 获取异常对象信息
try:
1 / 0
except ZeroDivisionError as e:
print(f"错误类型: {type(e).__name__}") # 输出: ZeroDivisionError
print(f"错误信息: {e}") # 输出: division by zero
print(f"错误轨迹: {e.__traceback__}") # 详细堆栈跟踪
3. else 子句(无异常时执行)
try:
num = int(input("输入数字: "))
except ValueError:
print("输入无效!")
else:
print(f"平方值: {num**2}") # 仅当无异常时执行
4. finally 块(始终执行)
file = None
try:
file = open("data.txt", "r")
process(file)
except FileNotFoundError:
print("文件不存在")
finally:
if file:
file.close() # 确保资源释放
print("操作结束")
三、高级异常处理技巧
1. 自定义异常类型
class AuthenticationError(Exception):
"""自定义认证异常"""
def __init__(self, message="认证失败"):
self.message = message
super().__init__(self.message)
# 使用示例
def login(username, password):
if not validate_credentials(username, password):
raise AuthenticationError("用户名或密码错误")
2. 异常链(Python 3+)
try:
process_data()
except DataError as e:
raise DatabaseError("数据存储失败") from e # 保留原始异常
3. 上下文管理器集成
from contextlib import contextmanager
@contextmanager
def safe_open(path, mode):
file = None
try:
file = open(path, mode)
yield file
except Exception as e:
print(f"文件操作失败: {e}")
raise
finally:
if file:
file.close()
# 使用示例
with safe_open("data.txt", "r") as f:
print(f.read())
四、最佳实践原则
精准捕获
- 避免裸露的
except:
(会捕获所有异常,包括 KeyboardInterrupt) - 优先捕获具体异常类型(如
ValueError
而非通用的Exception
)
- 避免裸露的
异常分类处理
- 业务逻辑异常(如
InvalidInputError
)与系统异常(如ConnectionError
)分层处理
- 业务逻辑异常(如
资源清理优先
- 使用
with
语句自动管理资源(文件/网络连接等) - 在
finally
块中执行必需清理操作
- 使用
日志记录规范
import logging logging.basicConfig(level=logging.ERROR) try: risky_operation() except SpecificError as e: logging.error("操作失败", exc_info=True) # 记录完整堆栈
异常转译
- 将底层异常转换为业务相关异常:
try: db.query("SELECT ...") except DatabaseError as e: raise UserVisibleError("数据查询失败") from e
- 将底层异常转换为业务相关异常:
五、常见错误模式
1. 空 except 块
try:
risky_code()
except: # 危险!会捕获所有异常
pass
2. 过度捕获
try:
parse_data(user_input)
except Exception: # 掩盖潜在编程错误
return default_value
3. 异常信息丢失
try:
1 / 0
except ZeroDivisionError:
raise RuntimeError("计算失败") # 丢失原始异常信息
六、调试技巧
查看完整堆栈跟踪
import traceback try: problematic_code() except: traceback.print_exc() # 打印完整错误信息
pdb 调试
import pdb; pdb.set_trace() # 在异常触发处启动调试器
异常断言
assert isinstance(value, int), "值必须为整数"
通过合理运用异常处理机制,可以显著提升代码健壮性。建议结合单元测试框架(如 pytest)验证异常处理逻辑,确保关键路径的容错能力。