以下是《【Python】异常处理:从基础到进阶》的系统教程,适合初学者入门,也覆盖了进阶用法,包括自定义异常、嵌套捕获、上下文管理器中的异常、日志集成、try/else/finally 的最佳实践等内容。


📘 目录

  1. 什么是异常
  2. Python 中的常见异常类型
  3. try…except 基础语法
  4. 捕获多个异常类型
  5. 使用 else 与 finally 子句
  6. 获取异常详情与 traceback 模块
  7. 自定义异常类
  8. 嵌套异常与异常链
  9. 异常与上下文管理器(with)
  10. 与日志 logging 模块结合使用
  11. 异常处理的最佳实践

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:)会隐藏所有错误
  • 捕获异常后什么都不做
  • 在不必要的地方加异常处理(例如性能敏感代码段)

📚 参考资料