Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 输入函数的记忆化_Python_Python Decorators_Memoization - Fatal编程技术网

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它肯定能工作。