Finally中代码一定会执行吗?
“大部分情况下会,但不能说‘一定’。我早期写过一段代码,在 try 里调了 os._exit(),结果 finally 里的清理全部跳过,内存泄漏查了半天。
🛡️ 一句话:
finally保证在离开try块时执行,但如果进程直接‘暴毙’,神仙也救不了它。”
✅ 会执行的情况(99% 的场景)¶
| 场景 | 说明 |
|---|---|
| 正常结束 | try 或 else 跑完 |
| 抛出异常 | 哪怕没被 except 捕获,也会先跑 finally 再向上抛 |
| return / break / continue | 先执行 finally,再真正返回或跳出 |
| sys.exit() | 它本质是抛出 SystemExit 异常,finally 能执行 |
小验证:
💥 不会执行的情况(进程“物理消失”)¶
| 场景 | 典型触发 |
|---|---|
| 调用 os._exit() | 直接终止进程,不抛异常,不清理 |
| 解释器崩溃 | C 扩展 segfault、栈溢出、内存踩踏 |
| 外部强杀信号 | kill -9、任务管理器强制结束 |
| 守护线程中的 finally | 主线程结束,守护线程被直接终止,finally 不保证运行 |
| 死循环或卡死 | 如果 try 里永远不出来,finally 自然没机会(但这不是语言不保证,是逻辑问题) |
🧪 快速分辨:会不会执行?¶
🎯 面试用一句话总结¶
🔧 “
finally保的是‘正常的离开路径’——异常、返回、跳出,它都能截住; 但面对os._exit()和kill -9这种‘暴力拆迁’,它一点办法都没有。 写关键清理逻辑,别只靠finally,结合atexit和信号处理才稳。”