finally 在正常流程、异常被捕获时必执行;但遇 sigkill、os._exit()、线程被强制终止、解释器致命错误时无法执行。

如果您在 Python 中使用 try-except-finally 结构,但发现 finally 子句似乎未按预期运行,则可能是由于程序在 try 或 except 块中遭遇了非正常终止。以下是分析 finally 执行时机的多个关键场景:
一、正常流程下 finally 必定执行
在 try 块无异常、或异常被 except 成功捕获并处理的情况下,finally 子句一定会执行,无论 try 或 except 中是否包含 return、break、continue 语句。该机制确保资源清理逻辑不被跳过。
1、定义一个含 finally 的函数,其中 try 块内含 return 语句。
2、调用该函数并观察返回值及 finally 内 print 输出。
立即学习 “Python 免费学习笔记(深入)”;
3、确认 finally 中的代码在 return 值确定后、实际返回前执行。
二、系统级中断导致 finally 不执行
当 Python 解释器进程被外部信号强制终止时,finally 无法获得执行机会。这类中断绕过了 Python 的正常控制流调度机制。
1、在运行含 finally 的脚本时,使用操作系统命令发送 SIGKILL(Linux/macOS 下 kill -9)。
2、观察终端输出,确认 finally 内部语句无任何打印。
3、SIGKILL 无法被捕获或忽略,因此 finally 绝对不执行 。
三、os._exit() 直接退出进程
os._exit() 绕过 Python 的正常退出流程,不触发任何 atexit 注册函数、不执行 finally、不刷新 I / O 缓冲区,直接终止当前进程。
1、在 try 块中调用 os._exit(0)。
2、确认后续 finally 块中所有语句均未执行。
3、 与 sys.exit() 不同,os._exit() 不会引发 SystemExit 异常,因此不会进入 finally。
四、线程被强制终止
在多线程环境中,若主线程调用 threading.Thread 对象的 stop() 方法(该方法实际不存在于标准库,此处指非安全强制终止手段),或通过外部机制杀掉线程,目标线程中正在执行的 finally 可能被截断。
1、启动一个子线程,其 run() 方法包含 try-finally 结构。
2、主线程使用非标准方式(如 ctypes 注入或信号)强行终止该线程。
3、Python 标准线程 API 不提供安全强制终止接口;任何绕过正常退出路径的操作都可能导致 finally 丢失 。
五、致命解释器错误
当 Python 解释器自身发生严重错误(如内存访问越界、栈溢出、GC 崩溃),进程会立即中止,所有 Python 层控制流(包括 finally)均无法继续。
1、构造递归深度远超 sys.getrecursionlimit() 的函数并在 try 中调用。
2、运行时触发 Segmentation Fault 或 Fatal Python error。
3、 此类错误发生在 C 运行时层面,Python 的异常处理机制完全失效 。






























