wim*_*wim 6 python stack-overflow recursion
在script.py:
def f(n, memo={0:0, 1:1}):
if n not in memo:
memo[n] = sum(f(n - i) for i in [1, 2])
return memo[n]
print(f(400))
Run Code Online (Sandbox Code Playgroud)
python3.6 script.py正确打印f(400),但随之而来的python3.7 script.py是堆栈溢出。f(501)递归限制在 3.6 和3.7 中达到f(334)。
Python 3.6 和 3.7 之间发生了什么变化导致此代码提前超出了最大递归深度?
在 Python 3.6.0b1 和 Python 3.7.0a1 之间进行一些 git 平分之后,我发现了bpo bug #29306 (git commits 7399a05, 620580f ),它识别了一些递归深度计数的错误。
\n最初,Victor Stinner 报告说,他不确定一些新的内部 API 函数是否用于优化调用(报告的调用开销优化的一部分)一部分)是否正确处理递归计数器,但经过进一步讨论后,确定问题更普遍,并且所有对 C 函数的调用也需要处理递归计数器。
\n链接问题中包含一个简单的测试脚本,该脚本表明旧版 Python 中也存在递归计数问题;该脚本依赖于一个特殊的扩展模块,该模块是开发树的一部分。然而,尽管 Python 版本 2.7、3.5 和 3.6 被证明受到影响,但这些更改从未向后移植。我猜测,由于这些版本没有收到调用开销优化,向后移植将需要大量工作。我还可以\xe2\x80\x99t 在Python 变更日志中找到此更改的条目,也许是因为 Victor 将此视为优化工作的一部分。
\n这些更改意味着sum()和其他内置函数现在计入递归调用限制,而它们以前没有\xe2\x80\x99t。