You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:实现统计Ackermann函数递归次数与执行时间的装饰器(现有代码运行异常)

修复Ackermann函数的递归次数与执行时间统计装饰器

我帮你排查下代码里的问题,主要是三个核心逻辑搞错了,咱们一步步来修正:

原代码的问题分析

  1. 调用次数统计完全错误:你把Ackermann函数的返回值(比如ackermann(2,2)返回7)直接赋值给了func.calls,这是把函数的计算结果和递归调用次数搞混了!Ackermann函数的返回值是数学计算结果,不是被调用的次数。
  2. 执行时间统计不对:当前代码会在每一次递归调用时都计算耗时,最后last_time_taken会被最后一层递归的时间覆盖,而不是整个顶层调用的总耗时。
  3. 计数器逻辑没用对:你定义的visualise.level只是跟踪递归深度,但完全没用来统计总调用次数,而且初始化位置也不对,没法正确累计次数。

修正后的完整代码

首先别忘了导入必要的模块,然后调整装饰器的逻辑:

import time
from functools import wraps

def visualise(func):
    # 给被装饰的函数初始化统计属性
    func.total_calls = 0
    func.last_time_taken = 0.0

    @wraps(func)
    def wrapper(*args, **kwargs):
        # 判断是否是顶层调用(首次进入当前调用链)
        is_top_level = wrapper.current_calls == 0
        if is_top_level:
            start_time = time.perf_counter()
        
        # 每次进入wrapper(不管是顶层还是递归)都计数+1
        wrapper.current_calls += 1
        try:
            # 执行原函数
            result = func(*args, **kwargs)
        finally:
            # 只有顶层调用结束时,才更新函数的统计属性并重置计数器
            if is_top_level:
                elapsed_time = time.perf_counter() - start_time
                func.last_time_taken = elapsed_time
                func.total_calls = wrapper.current_calls
                wrapper.current_calls = 0  # 重置计数器,准备下一次调用
        
        return result
    
    # 初始化wrapper的临时计数器,用于跟踪当前调用链的总次数
    wrapper.current_calls = 0
    return wrapper

@visualise
def ackermann(n, m):
    if n == 0:
        return m + 1
    elif m == 0:
        return ackermann(n - 1, 1)
    else:
        return ackermann(n - 1, ackermann(n, m - 1))

代码逻辑说明

  • 我们给wrapper加了一个current_calls临时属性,用来统计当前整个调用链的总次数,每次顶层调用结束后会重置,避免影响下一次调用。
  • 只有顶层调用时才会记录开始时间,结束后计算总耗时,确保last_time_taken是整个ackermann(2,2)调用的总时间,而不是某一层递归的时间。
  • 用try...finally保证即使函数出现异常(虽然Ackermann合法参数不会抛异常),计数器也能被正确重置,避免污染后续调用。

测试调用

现在执行你的测试代码:

ackermann(2, 2)
print(f"递归调用次数: {ackermann.total_calls}")  # 输出7,符合预期
print(f"总执行时间: {ackermann.last_time_taken} seconds")  # 输出类似0.00000034的时间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 01:17:28