导入函数的记忆

Posted

技术标签:

【中文标题】导入函数的记忆【英文标题】:Memoization of Imported Functions 【发布时间】:2020-11-07 18:34:26 【问题描述】:

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

我了解,将函数的记忆版本命名为与原始版本不同会导致效率低下,因为递归调用将激活未记忆的函数。 (见这个老问题,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 fibonacci import fibonacci 之后,你没有名字,你可以在下面存储装饰函数,fibonacci 会递归地找到它。改用import fibonacci,并使用fibonacci.fibonacci 申请并调用装饰器。 @jasonharper 大声笑,我自己就知道了。谢谢,快写出来,我会接受的.. @jasonharper 但这行得通吗?导入的函数将通过创建函数时已绑定的模块中的本地对象引用自身。 @MarkRansom 它确实有效。 【参考方案1】:

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))

【讨论】:

以上是关于导入函数的记忆的主要内容,如果未能解决你的问题,请参考以下文章

我想知道C++中怎么区分各种各种函数,有效记忆的,我现在学数据结构那里边各种函数看着头疼。谢谢。

JavaScript的记忆函数真的可以提升性能吗?

浅析js中的纯函数高阶函数记忆函数偏函数

浅析js中的纯函数高阶函数记忆函数偏函数

具有任意数量参数的函数的 C# 记忆[关闭]

useCallback 记忆函数和useMemo 记忆组件