Python异常处理完全指南 - 来自Python Cheatsheet项目
异常处理概述
在Python编程中,异常处理是应对程序运行时错误的关键机制。当程序遇到意外情况时(如除以零、文件不存在等),Python会抛出异常。如果不处理这些异常,程序会立即终止执行。
异常处理的核心思想是"预防胜于治疗"——通过合理的异常处理,我们可以:
- 防止程序意外崩溃
- 提供有意义的错误信息
- 在错误发生时执行必要的清理工作
- 实现更健壮的代码逻辑
基础异常处理
让我们从一个简单的除法函数开始,看看如何处理除零异常:
def divide(dividend, divisor):
try:
print(dividend / divisor)
except ZeroDivisionError:
print('除数不能为零')
在这个例子中:
try
块包含可能引发异常的代码except
块捕获特定异常并处理ZeroDivisionError
是Python内置的除零异常类型
处理多种异常
实际开发中,一个代码块可能抛出多种异常。Python允许我们同时捕获多种异常:
def process_file(filename):
try:
with open(filename) as f:
content = f.read()
number = int(content)
except (FileNotFoundError, ValueError) as e:
print(f"处理文件时出错: {str(e)}")
这种方式的优点:
- 代码更简洁,避免多个except块
- 相关异常可以统一处理
- 使用
as e
可以获取异常对象,提取错误信息
finally子句的妙用
finally
块中的代码无论是否发生异常都会执行,非常适合用于资源清理:
def database_operation():
conn = None
try:
conn = connect_to_database()
# 执行数据库操作
except DatabaseError as e:
print(f"数据库错误: {e}")
finally:
if conn: # 确保连接被关闭
conn.close()
print("数据库操作完成")
finally
的典型应用场景:
- 关闭文件句柄
- 释放数据库连接
- 释放网络资源
- 执行必要的清理操作
自定义异常
当内置异常无法满足需求时,我们可以创建自定义异常:
class InvalidAgeError(Exception):
"""年龄无效异常"""
def __init__(self, age, message="年龄必须在0-120之间"):
self.age = age
self.message = message
super().__init__(self.message)
def set_age(age):
if not 0 <= age <= 120:
raise InvalidAgeError(age)
print(f"年龄设置为: {age}")
自定义异常的最佳实践:
- 继承自基础Exception类
- 命名以"Error"结尾
- 可以提供有意义的默认错误信息
- 可以携带额外的错误上下文信息
异常处理的高级技巧
异常链
Python 3引入了异常链机制,可以保留原始异常信息:
try:
# 可能抛出异常的代码
except SomeError as e:
raise CustomError("附加信息") from e
上下文管理器与异常处理
结合with
语句可以更优雅地处理资源:
with open('file.txt') as f:
content = f.read()
即使f.read()
抛出异常,文件也会自动关闭。
日志记录与异常
生产环境中,应该记录异常而不仅仅是打印:
import logging
try:
risky_operation()
except Exception as e:
logging.exception("操作失败")
异常处理的最佳实践
- 具体优于宽泛:捕获特定异常而非所有异常
- 避免空的except块:至少要记录错误
- 保持try块精简:只包含可能抛出异常的代码
- 合理使用finally:确保资源释放
- 提供有意义的错误信息:帮助调试和用户理解
总结
Python的异常处理机制提供了强大的错误管理能力。通过合理使用try/except/finally结构、创建自定义异常以及遵循最佳实践,可以编写出更健壮、更易维护的Python代码。记住,良好的异常处理不仅能防止程序崩溃,还能提供清晰的错误诊断信息,是专业Python开发的重要技能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考