问题描述 投票:0回答:2
实际上有几个问题。 首先,正如

NPE的答案很好地解释了,python并没有消除尾巴呼叫,因此在Python中允许无限递归的功能受到限制。 正如NPE所解释的那样,second又一次无法消除呼叫堆栈上的空间。而且,即使在使用TCE的语言中,也有许多递归功能不能像迭代一样对待。 (考虑递归自称两次的幼稚斐波那契函数。)

但是,呼叫首先是有限资源? Python堆栈框架至少可以在堆上实现并链接在一起(有关该原理的存在证明,请参见-Stackless),在64位的内存空间中,有一个超过1000个堆栈框架的空间。 (实际上,即使在几乎任何现代平台上的C堆栈也可以容纳超过1000个递归Python口译员的电话。)

原因是原因是历史性的:python解释器使用固定的C堆栈在递归电话时递归地召集自身,最初是为32位(甚至24或20位)平台设计的,该平台很小。
但本来可以改变的,而Python 3.0将是改变它的理想场所。那么,为什么不呢?因为他们做出了有意识的语言设计决定。在Pythonic代码中,递归通常非常浅(例如,像prive the travers traver的浅树结构的代码);如果您的功能达到了1000个附近的深度,则比故意的更有可能是错误。因此,限制停留。当然,这是有点圆形的 - 如果他们删除了极限(尤其是,如果它们消除了尾声),则更深的递归将变得更加惯用。但这就是重点 -  Guido不想要一种深层递归是惯用的语言。 (大多数Python社区都同意)

python recursion stack
2个回答
27
投票

堆栈上,并且堆栈的大小受到限制。 仅列表不会消耗堆栈空间,因此不受此限制。

没有每个递归电话都需要消耗堆栈空间。例如,某些语言可以自动将

尾递归转换为迭代。但是,cpython选择不这样做(python优化尾部递归?

)。

您可以通过拨打python调用堆栈的最大深度。

回测需要在大小限制的call堆栈上的空间。使用过多递归的代码将产生一个错误的错误,称为“堆放溢出”(也以某些晦涩的网站闻名)。 Python似乎将其限制在1000级左右,但是通过设置

os.walk

.

可以增加此级别。 tiretration使用类似

sys.setrecursionlimit

循环的东西,它是通过将某些计数器增加并有条件地将
InstructionPointer

设置回循环开始的。这在内存中是恒定的。

21
投票
这不是Python语言规范,而是CPYTHON实现细节。旧版本的其他实现Python Pypy不使用堆栈,并且没有递归深度限制。

https://doc.pypy.org/en/latest/stackless.html#recursion-depth-limit 如果CPYTHON中的最大递归深度不满足您的需求,则您可能会尝试使用PYPY插入Python脚本。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.