You need to enable JavaScript to run this app. Python通过装饰器统计递归函数调用次数与最大递归深度
优惠活动
大模型
产品
解决方案
定价
更多

Python通过装饰器统计递归函数调用次数与最大递归深度

问题根因

现有实现的核心缺陷:

  • 计数器全局无差别累加,未识别递归链路的最外层调用入口,触发独立调用时不会重置历史统计值
  • 缺少递归执行状态标记,无法区分“单次独立调用的起始点”和“递归链路内部的嵌套调用”,导致多次跨调用的统计值持续叠加
正确实现方案

核心逻辑是通过状态标记区分递归根调用与嵌套调用:在根调用触发时重置统计值,递归链执行过程中持续计数、跟踪最大深度,递归链完全退出后恢复状态标记,供下次根调用触发重置。

def depthcounter(func):
    def wrapper(*args, **kwargs):
        # 识别当前是否为递归链路的最外层根调用
        is_root = not wrapper._active
        if is_root:
            # 根调用入口:重置本次链路的统计值
            wrapper.ncalls = 0
            wrapper.rdepth = 0
            wrapper._current_depth = 0
            wrapper._active = True
        
        # 累加调用计数、更新实时递归深度
        wrapper.ncalls += 1
        wrapper._current_depth += 1
        # 记录本次链路达到的最大递归深度
        if wrapper._current_depth > wrapper.rdepth:
            wrapper.rdepth = wrapper._current_depth
        
        try:
            result = func(*args, **kwargs)
        finally:
            # 递归栈回溯时实时更新当前深度
            wrapper._current_depth -= 1
            # 根调用栈帧弹出时,恢复活跃标记
            if is_root:
                wrapper._active = False
        return result

    # 初始化装饰器挂载的公开属性与内部状态
    wrapper.ncalls = 0
    wrapper.rdepth = 0
    wrapper._active = False
    wrapper._current_depth = 0
    return wrapper
验证效果

使用提供的阶乘测试代码,最终输出完全匹配预期:

0 0
4 4
10 10
10 10
20 20
2 2
方案特性
  • 兼容任意递归场景:无论线性递归还是带分支的递归(如斐波那契计算),均可正确统计总调用次数与最大递归深度
  • 异常安全:通过finally块处理状态恢复,即使被装饰函数抛出异常,也不会卡在活跃状态,保证后续调用可正常重置统计值
  • 无侵入性:装饰器不修改原函数的执行逻辑与参数传递规则,对业务代码完全透明

内容的提问来源于stack exchange,提问作者Daniil Khlebnikov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 03:06:01