【问题标题】:Number of calls of recursive function with python decorators使用 python 装饰器调用递归函数的次数
【发布时间】:2019-08-02 09:44:10
【问题描述】:

我有以下关于功能装饰器的代码块,我想在第二次调用fib() 时将变量wrapper.calls 初始化为0,因为我知道在第一次运行时它会给出正确答案之后,它的行为就像对以前的输出求和一样。我的问题是如何通过仅更改装饰器分析器来解决此问题?

这是我的代码:

from functools import wraps
import time


def profiler(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        wrapper.calls += 1
        return func(*args, **kwargs)
    wrapper.calls = 0
    return wrapper

@profiler
def fib(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)


fib(1)
print(fib.calls)
fib(2)
print(fib.calls)

此程序执行后的输出:

1
4

预期输出

1 
3

【问题讨论】:

    标签: python-3.x python-decorators


    【解决方案1】:

    因为calls = 0 仅在fib = profiler(fib) 处初始化。

    如果你只执行

    fib(2)
    print(fib.calls)
    

    它将是 3

    for input_n in (1, 2):
        fib = profiler(fib)
        fib(input_n)
        print(fib.calls)
    

    会如你所愿

    1
    3
    

    【讨论】:

    • 我想更改装饰器分析器以避免这种情况(执行后该程序的输出),而不是调用函数fib()的代码。
    【解决方案2】:
    def profiler(func):
    
        calls = 0
    
        @wraps(func)
        def wrapper(*args, **kwargs): 
            nonlocal calls
            if not calls:
                wrapper.calls = 0
    
            calls += 1
            result = func(*args, **kwargs)
            calls -= 1
            wrapper.calls += 1
    
            return result
        return wrapper
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-01
      • 2019-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-01
      • 2020-05-20
      • 2019-11-07
      相关资源
      最近更新 更多