finally几乎总执行,但前提是try块已开始运行;若在进入try前出错、os._exit()、sigkill、断电等系统级中断则不执行。

在 Python 中,finally 子句**几乎总是会执行**,但“一定”要加限定条件——它在 绝大多数正常退出和异常退出路径下都会执行,前提是 try 或 except 块已经进入执行阶段,且程序未被强制终止。
finally 执行的前提:try 块已开始运行
只有当控制流真正进入了 try 块(哪怕只执行了第一行),finally 才保证后续会运行。如果在进入 try 之前就发生了错误(比如函数调用前参数解析失败、语法错误、模块导入失败等),finally 根本不会被注册,自然不执行。
-
❌ 不会触发 finally:
func()[0]中func()返回None,抛出TypeError—— 错误发生在try外部 -
❌ 不会触发 finally:
try:上方有1/0,直接报错退出,try块根本没开始 -
✅ 会触发 finally: 进入
try后任意位置return、break、continue、抛异常、正常结束,都会走finally
finally 在 return 之后仍会执行(但不改变返回值)
这是最容易误解的一点:finally 会在 return 表达式求值完成、返回值已确定后执行;若 finally 中也有 return,则它会覆盖前面的返回值。
- 示例:
def f(): try: return 'from try' finally: print('in finally') # return 'from finally' ← 若取消注释,实际返回这个 - 执行顺序:计算
'from try'→ 暂存返回值 → 进入finally→ 打印 → (若无 return)返回暂存值 - 注意:若
finally中抛出新异常,原异常会被抑制(除非原异常还未被处理)
哪些情况 finally 可能“不执行”?
严格来说,是 Python 运行环境无法保证执行,属于系统级中断或非正常终止:
立即学习“Python免费学习笔记(深入)”;
-
os._exit():直接终止进程,绕过所有 Python 清理逻辑(包括
finally、__del__、atexit) - 进程被 kill -9(SIGKILL):操作系统强制杀死,Python 来不及响应
- 断电、内核崩溃、死循环卡死未触发解释器调度等极端情况
- C 扩展中发生致命错误(如 segfault)导致解释器异常退出
finally 的典型可靠用途
正因为它在绝大多数退出路径下都执行,适合做资源清理:
- 关闭文件、数据库连接、网络 socket
- 释放锁(
threading.Lock.release()) - 重置状态变量(如临时修改的全局 flag)
- 日志记录“操作结束”,无论成功或失败
不复杂但容易忽略:写 finally 前先确认你真进了 try,而不是在它外面就倒下了。









