Skip to content

Python 异常处理体系工程化

为什么要进行异常处理?

原因描述
增强程序稳定性捕获和处理异常,程序可以在遇到错误时继续运行,而不是崩溃。
错误信息反馈提供清晰的错误信息,帮助开发者快速定位问题。
资源管理确保在发生错误时适当地释放资源,避免资源泄露。
用户体验给用户提供友好的提示信息,而不是程序的堆栈跟踪。
逻辑控制控制程序逻辑流,在遇到非预期情况时采取备用方案。

Python 异常和错误体系

  • 异常(Exception)

    • 指程序执行过程中发生的事件,通常指示错误或其他异常情况。
    • Python 提供多种内置异常,如 ValueErrorTypeErrorIndexError
  • 错误(Error)

    • 通常指较严重的问题,导致程序无法继续运行。
    • 错误通常不能被捕获或处理,如 SyntaxErrorMemoryError
  • 异常处理结构

    • try 块:包含可能引发异常的代码。
    • except 块:用于捕获和处理特定的异常。
    • else 块:可选,在没有异常发生时执行。
    • finally 块:可选,无论是否发生异常都会执行,常用于清理资源。
  • 自定义异常

    • 通过继承 Exception 类定义自定义异常,便于在特定情况下抛出和捕获。

      python
      class MyCustomError(Exception):
          def __init__(self, message):
              super().__init__(message)
              self.message = message
  • 抛出异常

    • 使用 raise 关键字主动抛出异常,以便在特定条件下中断程序执行并转向异常处理。

异常处理流程

  1. try 块

    • 程序首先执行 try 块中的代码。
    • 如果 try 块中的代码没有发生异常:
      • 跳过所有的 except 块。
      • 继续执行 else 块(如果有)和 finally 块(如果有)。
  2. except 块

    • 如果 try 块中的代码发生了异常:
      • Python 将查找与该异常类型匹配的 except 块。
      • 如果找到匹配的 except 块,程序将执行该块中的代码。
      • 然后继续执行 finally 块(如果有)。
  3. else 块

    • 如果 try 块没有发生异常,且存在 else 块:
      • 程序将执行 else 块中的代码。
  4. finally 块

    • 无论是否发生异常,finally 块中的代码始终会被执行。
    • 这通常用于清理资源,比如关闭文件或网络连接。

自定义异常

  1. 继承内置异常:创建一个新的异常类,通常继承自 Exception 或其子类。
  2. 添加初始化方法:可以在类中定义 __init__ 方法,接收自定义的错误信息。
  3. 可选的字符串表示:重写 __str__ 方法,提供用户友好的错误信息。

最佳实践

  • 尽量具体:使用特定的异常类型捕获,而不是通用的 except。这有助于更准确地处理错误。

  • 记录日志:在捕获异常时,记录详细的错误信息,以便后续调试。

  • 避免静默失败:不要简单地忽略异常,确保有适当的处理逻辑或反馈。

  • 使用 finally 进行清理:在 finally 块中清理资源,确保无论是否发生异常都能正常关闭文件或网络连接。

  • 用户友好的错误提示:为用户提供清晰的错误信息,而不是技术细节。

  • 测试异常处理逻辑:编写单元测试,确保异常处理路径正常工作。

  • 避免嵌套的异常处理:保持代码简洁,避免过多的嵌套,影响可读性。