为何插入print()会影响Python递归计数器cnt的最终值?
为什么插入print()会改变递归计数器的最终值?
这段Python代码出现了不符合预期的行为:启用函数f内的print(' >', s, cnt)语句时,全局计数器cnt最终值为2;注释该语句时,cnt最终值为3。明明通过setrecursionlimit(10)将递归深度设为10,为什么插入print()会影响cnt的最终值?
示例代码
from sys import getrecursionlimit, setrecursionlimit setrecursionlimit(10) print(f'sys: maxRecursionDepth = {getrecursionlimit()}') cnt = 0 def f(s): global cnt #print(' >', s, cnt) # <<<< 改变了'cnt'的最终值!!! cnt += 1 print('>>>', s, cnt) eval(s) # --- try: f("f(s)") except RecursionError: print(f'f() maxRecursionDepth = {cnt}') # RecursionError: maximum recursion depth exceeded
两种场景的输出
启用print语句时的输出
sys: maxRecursionDepth = 10 > f(s) 0 >>> f(s) 1 > f(s) 1 >>> f(s) 2 f() maxRecursionDepth = 2
注释print语句时的输出
sys: maxRecursionDepth = 10 >>> f(s) 1 >>> f(s) 2 f() maxRecursionDepth = 3
原因分析
核心原因是Python的递归深度限制针对的是解释器的总调用栈深度,而非仅用户编写的递归函数调用次数,print()函数本身会引入额外的栈帧,挤占了递归可用的深度空间:
setrecursionlimit()设置的是解释器允许的所有函数调用的总栈深度,包括标准库函数、解释器内部的辅助调用,不是你写的f()函数的调用次数。- 启用
print()后,每次调用f()都会额外触发print()的执行,而print()内部还会调用字符串格式化、IO流写入等一系列函数,这些都会增加当前的栈深度。 - 无
print()时,递归到第3次调用f()时,加上eval()、异常处理等内部调用,总栈深度刚好达到10触发RecursionError;而有print()时,额外的栈帧让总深度提前在第2次递归后就触及上限,导致cnt只增加到2就抛出异常。
内容的提问来源于stack exchange,提问作者user7711283
相关产品推荐
相关产品推荐

