Python 异常处理规范 | Google 官方最佳实践

2025-07-22 11:50 更新

异常

Tip

允许使用异常, 但必须谨慎使用.

定义:

异常是一种跳出正常的控制流,以处理错误或其它异常情况的方法。

优点:

处理正常情况的控制流不会和错误处理代码混在一起。
在特定情况下,它也能让控制流跳出多层调用帧。
例如,一步跳出N多层嵌套的函数,而不必逐层传递错误代码。

缺点:

可能导致控制流晦涩难懂。
调用库函数时容易忘记处理异常。

结论:

使用异常时必须遵守特定要求:

  1. 优先使用合适的内置异常类。
    比如,用 ValueError 表示前置条件错误 (例如给必须为正数的参数传入了负值)。 不要使用 assert 语句来验证公开API的参数值。应该用 assert 来保证内部正确性,不应该用 assert 来纠正参数或表示意外情况。若要用异常来表示意外情况,应该用 raise
    例如:
    正确:

    def connect_to_next_port(self, minimum: int) -> int:
    """连接到下一个可用的端口.
    
    
    
    
    参数:
        minimum: 一个大于等于 1024 的端口号.
    
    
    
    
    返回:
        新的最小端口.
    
    
    
    
    抛出:
        ConnectionError: 没有可用的端口.
    """
    if minimum < 1024:
        # 注意这里抛出 ValueError 的情况没有在文档里说明,因为 API 的
        # 错误用法应该是未定义行为.
        raise ValueError(f'最小端口号至少为 1024,不能是 {minimum}.')
    port = self._find_next_open_port(minimum)
    if port is None:
        raise ConnectionError(
            f'未能通过 {minimum} 或更高的端口号连接到服务.')
    assert port >= minimum, (
        f'意外的端口号 {port}, 端口号不应小于 {minimum}.')
    return port

    错误:

    def connect_to_next_port(self, minimum: int) -> int:
    """连接到下一个可用的端口.
    
    
    
    
    参数:
        minimum: 一个大于等于 1024 的端口号.
    
    
    
    
    返回:
        新的最小端口.
    """
    assert minimum >= 1024, '最小端口号至少为 1024.'
    port = self._find_next_open_port(minimum)
    assert port is not None
    return port

  2. 模块或包可以定义自己的异常类型,这些类必须继承已有的异常类。异常类型名应该以 Error 为后缀,并且不应该有重复(例如 foo.FooError)。
  3. 永远不要使用 except: 语句来捕获所有异常,也不要捕获 Exception 或者 StandardError ,除非你想:

    1. 重新抛出异常。
    2. 在程序中创造一个隔离点,记录并抑制异常,让异常不再继续传播。这种写法可以用在线程的最外层,以避免程序崩溃。

    如果你使用这种写法,Python 将非常宽容。 except: 真的会捕获任何错误,包括拼写错误的符号名、 sys.exit() 调用、 Ctrl+C 中断、单元测试错误和各种你不想捕获的错误。

  4. 最小化 try/except 代码块中的代码量。try 的范围越大,就越容易把你没想到的那些能抛出异常的代码囊括在内。这样的话,try/except 代码块就掩盖了真正的错误。
  5. 用 finally 表示无论异常与否都应执行的代码。这种写法常用于清理资源,例如关闭文件。
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号