导入函数的记忆

我正在创建一个装饰器来说明记忆。对于大多数人来说,我使用的是递归定义的 Fibonacci 函数。


我知道命名函数的记忆版本与原始版本不同会导致效率低下,因为递归调用将激活未记忆的函数。(参见这个老问题,Memoization python 函数)


我的问题是我似乎找不到正确的语法来覆盖导入函数的名称。


from fibonacci import fibonacci


def with_memoization(function):

    past_results = {}


    def function_with_memoization(*args):

        if args not in past_results:

            past_results[args] = function(*args)

        return past_results[args]

    return function_with_memoization



def fib(n):

    if n == 0:

        return 0

    elif n == 1:

        return 1

    else:

        return fib(n-1) + fib(n-2)



fib = with_memoization(fib)

fibonacci = with_memoization(fibonacci)


print(fib(100)) # completes in <1 second

print(fibonacci(100)) # completes in >2 minutes, probably hours

这里导入的斐波那契函数和fib函数是一样的。我错过了什么?


慕虎7371278
浏览 94回答 1
1回答

aluckdog

该from module import function语句将模块中的函数别名为function. 因此,当它被装饰时,只有别名被装饰。递归调用是针对未别名函数(在模块中),即未修饰的函数。您可以将此视为创建部分内存,别名函数将记住其自身计算的结果,但不会记住中间步骤。在上面的代码中,fibonacci(100)完成后将是字典中的唯一条目。(不要等待它。)使用import module语法不会为函数起别名,module.function它是“真实”名称。因此,应用于的装饰fibonacci.fibonacci也将装饰被递归调用的函数。工作实施:import fibonaccidef with_memoization(function):&nbsp; &nbsp; past_results = {}&nbsp; &nbsp; def function_with_memoization(*args, **kwargs):&nbsp; &nbsp; &nbsp; &nbsp; if args not in past_results:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; past_results[args] = function(*args, **kwargs)&nbsp; &nbsp; &nbsp; &nbsp; return past_results[args]&nbsp; &nbsp; return function_with_memoizationfibonacci.fibonacci = with_memoization(fibonacci.fibonacci)print(fibonacci.fibonacci(100))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python