标准答案

  1. __enter__/__exit__ 或 __aenter__/__aexit__ 定义资源生命周期。
  2. 即使代码块抛异常也会调用退出逻辑,退出函数是否吞异常必须明确。
  3. 连接、锁、文件和事务都要在正确作用域使用,不能把已关闭资源返回给后台任务。
  4. 取消时清理函数也要有界,不能在关闭阶段无限等待下游。

题目解析

上下文管理器把获取和释放绑定到 with 作用域,异常也会进入 __exit__/__aexit__。退出函数返回 True 会吞掉异常,因此只有明确完成恢复时才这样做。

async with 适合需要 await 关闭的连接、锁和客户端;资源对象不应在作用域结束后继续被后台任务引用。事务提交、回滚和外部副作用仍需业务设计。

取消发生在清理阶段时也要设置边界,不能让关闭逻辑无限等待下游。部分初始化失败时要只释放已经成功获取的资源。

常见误区

  • 误区:__exit__ 返回 True 吞掉所有异常。改正:只有完成明确恢复时才吞异常,否则保留根因。
  • 误区:async 资源使用普通 with。改正:使用 async with 并在取消、异常和关闭路径测试释放。
  • 误区:资源对象逃出 with 后继续使用。改正:让对象生命周期不超过上下文,后台任务复制必要数据。

作者信息