finally 总在离开 try-finally 结构时执行,无论异常是否发生或被处理、是否 return/break;若 finally 无 return,则返回原值,有则覆盖;异常未捕获时仍执行,但其中抛异常会抑制原异常。

finally 会在 try 或 except 中的代码执行完毕后立即执行,无论是否发生异常、是否被处理、是否主动 return 或 break。
finally 的触发条件
只要进入了 try 语句块(哪怕只执行了一行),且程序未因 os._exit()、进程被 kill 等底层方式强制终止,就一定会执行对应的 finally 块。
- try 中无异常 → 执行完 try 后执行 finally
- try 中抛异常且被 except 捕获 → 执行完 except 后执行 finally
- try 中抛异常但未被当前 except 捕获 → 在异常向外传播前,先执行 finally
- try 或 except 中遇到 return / break / continue → 暂存返回值或跳转意图,先执行 finally,再继续原操作
return 遇上 finally:谁胜出?
如果 try 或 except 中有 return,Python 会记住这个返回值,但不会立刻退出函数;而是转入 finally 执行。若 finally 中没有 return,函数最终仍返回原值;若 finally 中也有 return,则覆盖原先的返回值。
例如:
立即学习“Python免费学习笔记(深入)”;
def f():try:
return 'from try'
finally:
print('in finally')
# 没有 return → 返回 'from try'
print(f()) # 输出 'in finally' 和 'from try'
异常未被捕获时的 finally 行为
当 try 中抛出异常,又没有匹配的 except 处理,异常会向调用栈上传,但 Python 保证在离开当前 try-finally 结构前执行 finally。
- finally 可用于清理资源(如关闭文件、释放锁),即使程序即将崩溃也尽量执行
- 若 finally 中也抛出新异常,则原异常会被抑制(__context__ 保留),最终只传播 finally 中的异常
- 若 finally 中执行了 return,原异常将完全丢失
常见误区提醒
finally 不是“函数结束时才执行”,而是“离开 try-finally 结构时执行”。它不等待外层代码,也不受外层控制流影响。
- 不要在 finally 里写可能失败的逻辑(如再打开一个可能出错的文件),否则可能掩盖原始问题
- 避免在 finally 中 return,除非你明确需要覆盖结果(比如日志兜底返回)
- os._exit()、sys.exit()(后者可被捕获)、信号终止等场景下,finally 可能不执行









