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

Python使用timer_func装饰器统计递归斐波那契耗时重复打印日志问题

问题原因
  • 首先是装饰器被重复嵌套:你已经用@timer_func语法糖给fibonacci函数加了一层装饰,此时fibonacci本身已经是带计时逻辑的包装函数,后续调用timer_func(fibonacci)(5)等于又给它套了第二层计时装饰,两层逻辑同时生效。
  • 核心原因是递归调用触发了多次装饰逻辑:被装饰后的fibonacci函数每次递归调用fibonacci(x-1)、fibonacci(x-2)时,本质都是在调用带计时逻辑的包装函数,每执行一次递归就会打印一次耗时日志,自然会出现多条打印结果,而非仅统计最外层的总耗时。
解决方案

这里提供两种常用的修复方式:

方案1:仅对最外层调用加计时,不装饰递归函数

移除fibonacci函数上的@timer_func装饰器,只在需要统计耗时的最外层调用时套装饰器即可,此时递归内部调用的是原生未被装饰的fibonacci,不会触发多次打印:

from time import perf_counter
import logging

def timer_func(func):
    def inner_func(*args):
        t1 = perf_counter()
        res = func(*args)
        t2 = perf_counter()
        logging.log(logging.INFO, f"Done in {t2 - t1} Seconds!")
        return res
    return inner_func

# 移除此处的@timer_func装饰
def fibonacci(x: int):
    if x > 2:
        return fibonacci(x - 1) + fibonacci(x - 2)
    elif x == 1 or x == 2:
        return 1

# 仅最外层调用加计时
r = timer_func(fibonacci)(5)
print("Fibonacci %d of is %d" % (5, r))

方案2:给装饰器增加最外层调用判断,保留对函数的装饰

如果希望fibonacci本身自带计时能力、仅统计首次调用的总耗时,可以给装饰器加个调用层级标记,只有最外层调用执行完成后才打印日志:

from time import perf_counter
import logging

def timer_func(func):
    call_depth = 0
    def inner_func(*args):
        nonlocal call_depth
        t1 = perf_counter() if call_depth == 0 else None
        call_depth += 1
        res = func(*args)
        call_depth -= 1
        if call_depth == 0:
            t2 = perf_counter()
            logging.log(logging.INFO, f"Done in {t2 - t1} Seconds!")
        return res
    return inner_func

@timer_func
def fibonacci(x: int):
    if x > 2:
        return fibonacci(x - 1) + fibonacci(x - 2)
    elif x == 1 or x == 2:
        return 1

# 直接调用即可,无需再额外套一层timer_func
r = fibonacci(5)
print("Fibonacci %d of is %d" % (5, r))

额外注意:已经用@timer_func装饰过的函数,直接调用即可,不需要再额外套timer_func(fibonacci),否则会重复添加装饰逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:54:02