🐍Python 函数与面向对象
异常与上下文管理器
面试回答
常见问法
try/except/else/finally四个分支分别什么时候执行?with语句背后做了什么?__enter__、__exit__怎么写?- 怎么自定义异常?什么时候该抛、什么时候该吞?
contextlib里contextmanager、ExitStack、suppress分别用在什么场景?
回答
待补充:从「资源生命周期管理」和「错误传播语义」两条主线讲,强调「EAFP(easier to ask forgiveness than permission)」风格在 Python 里为什么主流。
追问
except Exception as e和裸except有什么危险差异?- 异常链
raise X from Y是什么? __exit__返回 True 会发生什么?- 异步 with(
async with)怎么写?
原理展开
- 四分支执行顺序:
try → [except|else] → finally - 上下文管理器协议:
__enter__返回资源,__exit__(exc_type, exc_val, tb)清理 @contextmanager装饰器:用生成器写 context managerExitStack:动态组合多个 context manager- 异常链:
raise NewError() from old_error,保留__cause__ contextlib.suppress:替代「空 except」的干净写法
易错点
- 裸
except:吞掉KeyboardInterrupt和SystemExit finally里return会覆盖 try 里的返回值- 自定义
__exit__返回 True,无声吞异常 - 忘记
with本质是「编译器生成 try/finally」,而不是语法糖那么简单
记忆技巧
- 四分支口诀:try 跑 / except 接 / else 顺利 / finally 必走
- with 本质:进入拿资源,退出必清理,异常不影响清理
- EAFP 口诀:先做再说,错了再抓,比事前检查更 Pythonic