递归函数装饰器

Decorators for recursion function

我想编写一个装饰器来计算计算斐波那契数 5(fib(5)) 10 次的函数的运行时间,并打印一个中等运行时间值。但是我的装饰器 returns 出错了。如何解决这个问题?

import functools
import time

def trace(times):
    def cache(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            total = 0
            for i in range(times):
                start = time.time()
                func(*args, **kwargs)
                end = time.time()
                total += (end - start)
            print('Medium value is {}'.format(total / times))
            return func
        return wrapper
    return cache

@trace(times=10)
def fib(num):
    if num < 2:
        return num
    return fib(num - 1) + fib(num - 2)

fib(5)

首先,在 wrapper return 结果中 returning func 而不是

我们必须确保跟踪仅发生在对递归调用的 fib 和 none 的第一次调用中。让我们使用布尔值 traced 参数:

import functools
import time

def trace(times):
    def cache(func):
        @functools.wraps(func)
        def wrapper(*args, traced=True, **kwargs):
            if not traced:
                return func(*args, **kwargs)
            total = 0
            for i in range(times):
                start = time.time()
                result = func(*args, **kwargs)
                end = time.time()
                total += (end - start)
                print(f'run {i}, time is {total}')
            print(f'Mean value is {total / times}')
            return result
        return wrapper
    return cache


@trace(times=10)
def fib(num, traced=True):
    if num < 2:
        return num
    return fib(num - 1, traced=False) + fib(num - 2, traced=False)


fib(5)

traced 默认为 True,因此将跟踪对 fib(n) 的任何调用(用户无需注意 traced 参数)。但是递归调用都有 traced=False 因此它们不会触发装饰器中的循环。