导入函数的记忆

Memoization of Imported Functions

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

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

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

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函数是一样的。我错过了什么?

from module import function 语句将模块中的函数别名为 function。因此,当它被装饰时,只有别名被装饰。递归调用是对未别名函数(在模块中),即未修饰的函数。

您可以将此视为创建部分内存,别名函数将记住其自身计算的结果,但不会记住中间步骤。在上面的代码中,完成后 fibonacci(100) 将是字典中的唯一条目。 (不要等待它。)

使用 import module 语法不会为函数添加别名,module.function 是它的 'real' 名称。因此,应用于 fibonacci.fibonacci 的装饰也将装饰被递归调用的函数。

工作实施:

import fibonacci

def with_memoization(function):

    past_results = {}

    def function_with_memoization(*args, **kwargs):
        if args not in past_results:
            past_results[args] = function(*args, **kwargs)
        return past_results[args]
    return function_with_memoization


fibonacci.fibonacci = with_memoization(fibonacci.fibonacci)

print(fibonacci.fibonacci(100))