以下是《【Python】异常处理:从基础到进阶》的系统教程,适合初学者入门,也覆盖了进阶用法,包括自定义异常、嵌套捕获、上下文管理器中的异常、日志集成、try/else/finally 的最佳实践等内容。
📘 目录
- 什么是异常
- Python 中的常见异常类型
- try…except 基础语法
- 捕获多个异常类型
- 使用 else 与 finally 子句
- 获取异常详情与 traceback 模块
- 自定义异常类
- 嵌套异常与异常链
- 异常与上下文管理器(with)
- 与日志 logging 模块结合使用
- 异常处理的最佳实践
1. 什么是异常
异常(Exception)是程序运行过程中出现的错误。若不处理,Python 会终止程序并输出 traceback。
print(10 / 0) # ZeroDivisionError: division by zero
2. Python 中的常见异常类型
异常类型 | 含义 |
---|---|
ZeroDivisionError | 除零错误 |
TypeError | 类型不匹配 |
ValueError | 值错误(如不能转换的字符串) |
IndexError | 索引越界 |
KeyError | 字典中键不存在 |
FileNotFoundError | 文件未找到 |
ImportError | 模块导入失败 |
AttributeError | 无该属性 |
NameError | 变量未定义 |
RuntimeError | 通用运行时错误 |
3. try…except 基础语法
try:
result = 10 / 0
except ZeroDivisionError:
print("除数不能为 0")
4. 捕获多个异常类型
使用多个 except 块
try:
x = int("abc")
except ValueError:
print("值错误")
except TypeError:
print("类型错误")
捕获多个异常为一个
try:
x = int("abc")
except (ValueError, TypeError) as e:
print(f"捕获异常:{e}")
5. 使用 else 与 finally 子句
else
: try 中无异常时执行finally
: 不管是否有异常都执行(如关闭文件、释放资源)
try:
result = 10 / 2
except ZeroDivisionError:
print("出错")
else:
print("执行成功")
finally:
print("清理资源")
6. 获取异常详情与 traceback 模块
import traceback
try:
1 / 0
except Exception as e:
print("异常类型:", type(e).__name__)
print("异常信息:", e)
traceback.print_exc()
7. 自定义异常类
class MyCustomError(Exception):
pass
def validate_age(age):
if age < 0:
raise MyCustomError("年龄不能为负数")
try:
validate_age(-5)
except MyCustomError as e:
print("自定义异常:", e)
8. 嵌套异常与异常链(raise from)
try:
try:
raise ValueError("原始异常")
except ValueError as e:
raise RuntimeError("包装后的异常") from e
except RuntimeError as e:
print("异常链:", e)
9. 异常与上下文管理器(with)
文件操作常用 with 自动处理资源释放:
try:
with open("nofile.txt") as f:
data = f.read()
except FileNotFoundError:
print("找不到文件")
10. 与日志 logging 模块结合使用
import logging
logging.basicConfig(level=logging.ERROR)
try:
1 / 0
except ZeroDivisionError:
logging.exception("除法错误")
使用 logging.exception()
会自动附带 traceback 信息,非常适合生产环境调试。
11. 异常处理的最佳实践
✅ 推荐:
- 精确捕获异常类型
- 使用
else
来避免在try
中包裹过多代码 - 利用
finally
清理资源 - 自定义异常用于更清晰的错误定义
- 捕获异常后应记录或反馈,不要直接
pass
❌ 避免:
- 使用空的 except(如
except:
)会隐藏所有错误 - 捕获异常后什么都不做
- 在不必要的地方加异常处理(例如性能敏感代码段)
📚 参考资料
- 官方文档:Errors and Exceptions
- logging 文档:Logging HOWTO
发表回复