我正在创建一个装饰器来说明内存。对于大多数人来说,我使用的是递归定义的斐波那契函数。
我知道以与原始函数不同的方式命名函数的内存版本会导致效率低下,因为递归调用将激活未内存的函数。 (参见这个老问题,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
这里导入的fibonacci函数和fib函数是一样的。我错过了什么?
最佳答案
from module import function
语句将模块中的函数别名为function
。因此,当它被装饰时,只有别名被装饰。递归调用是对未别名函数(在模块中),即未修饰的函数。
您可以将此视为创建部分内存,别名函数将记住其自身计算的结果,但不会记住中间步骤。在上面的代码中,完成后,fibonacci(100)
将成为字典中的唯一条目。 (不要等待它。)
使用 import module
语法不会给函数起别名,module.function
是它的“真实”名称。因此,应用于 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))
关于python - 导入函数的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62962678/