Python 3:我的装饰函数运行两次

时间:2017-12-29 17:32:43

标签: python python-3.x function

我有一些简单的斐波纳契序列函数,我正在练习单元测试并使用Travis-CI / Docker构建:

fib_recursive.py:

from fib.fib import benchmark, fib_rec_memo

@benchmark
def print_fib(n):
    for x in range(0, n):
        print(fib_rec_memo(x))

print_fib(100)

这是fib.fib导入源代码:

from time import time
from functools import wraps

def benchmark(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        t = time()
        func(*args, **kwargs)
        print(func.__name__, 'took:', time() - t)
        return func(*args, **kwargs)
    return wrapper


def fib_rec_memo(n, hash = {0:1, 1:1}):
    if n not in hash:
        hash[n] = fib_rec_memo(n-1) + fib_rec_memo(n-2)
    return hash[n]


@benchmark
def fib_standard(num):
    a, b = 0, 1
    c = []
    while a < num:            # First iteration:
        c.append(a)            # yield 0 to start with and then
        a, b = b, a + b    # a will now be 1, and b will also be 1, (0 + 1)
    return c

由于某种原因,执行python3 ./fib_recursive.py会启动该函数两次:

# python3 ./fib_recursive.py
1
1
2
3
5
8
13
21
34
55
print_fib took: 0.00011181831359863281
1
1
2
3
5
8
13
21
34
55
#

有谁知道为什么?

感谢。

1 个答案:

答案 0 :(得分:7)

您在wrapper函数中调用了两次修饰函数:

func(*args, **kwargs)  # here ...
print(func.__name__, 'took:', time() - t)
return func(*args, **kwargs)  # ... and here again

您可以通过将结果存储到变量并在定时输出后返回存储的结果来避免这种情况:

rval = func(*args, **kwargs)  # call it once and store result ...
print(func.__name__, 'took:', time() - t)
return rval  # ... then return result