实际上这里有几个问题。在
首先,正如NPE's answer很好地解释的那样,Python并没有消除尾部调用,所以在Python中允许无限递归的函数(比如Scheme)是有限的。在
其次,正如NPE所解释的那样,无法消除的调用会占用调用堆栈上的空间。而且,即使在进行TCE的语言中,也有许多递归函数不能像迭代一样处理。(考虑一个简单的Fibonacci函数,它递归地调用自己两次。)
但是为什么调用堆栈首先是一个有限的资源?Python堆栈帧至少原则上可以在堆上实现并链接在一起(请参阅Stackless以获取该原理的存在性证明),在64位内存空间中,可以容纳1000多个堆栈帧。(事实上,即使是在几乎任何现代平台上的C堆栈也可以容纳超过1000个递归Python解释器调用)
部分原因是历史的:每当您进行递归调用时,stock Python解释器使用固定的C堆栈递归地调用自己,它最初是为32位(甚至是24位或20位)平台设计的,在这些平台上,C堆栈非常小。在
但这是可以改变的,python3.0将是一个完美的改变它的地方。那么,他们为什么不呢?因为他们做出了有意识的语言设计决定。在python代码中,递归通常非常浅(例如,os.walk这样的代码遍历浅层树结构);如果函数的深度接近1000,那么它很可能是一个bug,而不是有意的。所以,限制依然存在。当然,如果去掉了限制(尤其是如果消除了尾部调用),则更深层次的递归将变得更加惯用。但这正是Guido不希望使用深度递归的惯用语言。(大多数Python社区都同意。)