Python 输入函数的记忆化
我正在创建一个装饰器来说明备忘录。对于大多数人来说,我使用的是递归定义的斐波那契函数Python 输入函数的记忆化,python,python-decorators,memoization,Python,Python Decorators,Memoization,我正在创建一个装饰器来说明备忘录。对于大多数人来说,我使用的是递归定义的斐波那契函数 from fibonacci import fibonacci def with_memoization(function): past_results = {} def function_with_memoization(*args): if args not in past_results: past_results[args] = functio
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
我理解,将函数的记忆版本命名为不同于原始版本将导致效率低下,因为递归调用将激活未记忆的函数。(看这个老问题,)
我的问题是我似乎找不到正确的语法来覆盖导入函数的名称
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
从斐波那契导入斐波那契
带记忆功能的def(功能):
过去的_结果={}
带记忆功能的def函数(*args):
如果参数不在过去的结果中:
过去的_结果[args]=函数(*args)
返回过去的_结果[args]
带记忆的返回函数
def纤维(n):
如果n==0:
返回0
elif n==1:
返回1
其他:
返回fib(n-1)+fib(n-2)
fib=带记忆(fib)
斐波那契=带记忆(斐波那契)
打印(fib(100))#在2分钟内完成,可能需要几个小时
这里导入的fibonacci函数和fib函数是相同的。我缺少什么?来自模块导入函数的
语句将模块中的函数别名为函数。因此,当它被修饰时,只有别名被修饰。递归调用是对未关联函数(在模块中)的调用,即未修饰的函数
您可以将其视为创建部分内存,别名函数将记住其自身计算的结果,但不会记住中间步骤。在上面的代码中,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))
问题是导入的函数在模块的名称空间中查找其名称,而不是在重新定义函数的名称空间中查找。从fibonacci import fibonacci
中的之后,您没有名称,您可以将修饰后的函数存储在该名称下,该名称将由fibonacci
递归查找。请尝试导入fibonacci
,然后使用fibonacci.fibonacci
应用并调用装饰程序。@jasonharper Lol,我自己刚得到。谢谢,快写出来,我会接受的。@jasonharper,但这样行吗?导入的函数将通过模块中的本地对象引用自身,该对象在创建函数时已绑定。@markransem它肯定能工作。