You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归代码中未触发预期条件的finally块为何仍执行并输出对应打印内容?

递归代码中未触发预期条件的finally块为何仍执行并输出对应打印内容?

嘿,这个问题问得挺有意思的,我来给你拆解一下到底发生了什么~

首先先把你的代码贴出来方便分析:

def divisive_recursion(n):
    try:
        if n <= 0:
            return 1
        else:
            return n + divisive_recursion(n // divisive_recursion(n - 1))
    except ZeroDivisionError:
        return -1
    finally:
        if n == 2:
            print("Finally block executed for n=2")
        elif n == 1:
            print("Finally block executed for n=1")

print(divisive_recursion(5))

你疑惑的点在于:明明divisive_recursion(1)陷入了无限递归,为什么finally里n=1和n=2的打印语句都会执行?其实核心原因是Python在处理递归深度溢出的RecursionError时,会回溯整个调用栈,每个栈帧对应的函数的finally块都会被强制执行,不管这个函数有没有正常返回。

具体的调用和执行流程是这样的:

  1. 当你调用divisive_recursion(5),它会依次触发divisive_recursion(4)→divisive_recursion(3)→divisive_recursion(2)→divisive_recursion(1)。
  2. 到divisive_recursion(1)时,计算n // divisive_recursion(n-1):n-1=0,divisive_recursion(0)返回1,所以1//1=1,于是divisive_recursion(1)会递归调用它自己,进入无限循环。
  3. 当递归次数超过Python的默认递归深度限制时,会抛出RecursionError。这时候Python会从最底层的栈帧开始,逐层向上清理调用栈,每清理一个栈帧,就会执行对应函数里的finally块。

这时候关键的点来了:

  • 栈里存在一个divisive_recursion(2)的帧(就是从divisive_recursion(3)调用过来的那个),当回溯到这个帧时,n的值是2,所以finally里的n==2条件成立,就会打印Finally block executed for n=2。
  • 栈里还有大量divisive_recursion(1)的帧(无限递归产生的),每回溯到一个这样的帧,n的值都是1,所以finally里的n==1条件成立,就会打印Finally block executed for n=1(你可能会看到这个打印多次,因为栈里有很多这样的帧)。

你之前误以为“n永远不会等于1或2”,但实际上divisive_recursion(2)和divisive_recursion(1)都被实实在在地调用过,只是因为无限递归没正常返回,但异常回溯时,这些函数的finally块都会被触发执行,自然就会打印出对应的内容啦。

备注:内容来源于stack exchange,提问作者Puna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:37:58