递归限制是包含的还是排除的?额外的堆栈帧从何而来?

5 python recursion

我有这个递归阶乘函数:

def factorial(n):
    if n < 2:
        return 1
    return n * factorial(n-1)
Run Code Online (Sandbox Code Playgroud)

正在做factorial(998)工作,但factorial(999)会提高RecursionError: maximum recursion depth exceeded in comparison.

为什么它在factorial(999)和 上出错而不是1000or 1001factorial(1)达到基本情况,因此调用函数时应该只有一个堆栈帧factorialfactorial(2)递归一次,因此应该使用 2 个堆栈帧,依此类推。

递归限制是排他的还是包含的?例如,当达到1000 个堆栈帧或超过setrecursionlimit(1000)1000 个堆栈帧时,是否会出错?

如果它是排他性的,为什么它会出错n=999而不是出错n=1000n=999应该创建 999 帧,而不是 1000。额外的堆栈帧从哪里来,使它达到 1000?如果包含限制,那么额外的 2 个堆栈帧从何而来,使其达到 1001 个堆栈帧?

Raf*_*alS 3

你自己看。Python 有很棒的自省工具:

import inspect

def factorial(n):
    if n < 2:
        return 1
    print(len(inspect.stack()))
    return n * factorial(n-1)
Run Code Online (Sandbox Code Playgroud)

全局级别已经为 1 深度。第一个函数调用是 2 深度的,因此计算中存在一个“额外”堆栈帧。

def f():
    print(len(inspect.stack()))

print(len(inspect.stack())) # 1
f() # 2
Run Code Online (Sandbox Code Playgroud)