python - 导入函数的内存

标签 python python-decorators memoization

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

我知道以与原始函数不同的方式命名函数的内存版本会导致效率低下,因为递归调用将激活未内存的函数。 (参见这个老问题,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/

相关文章:

python - 在 Python 中尝试/排除 : How to avoid duplication?

python - 数据如何在装饰函数的多次调用中保持持久?

python - 在Python中通过jq从API过滤JSON

python - 连接或游标上是否使用了提交?

python - 使用常量初始化时,Tensorflow 使用过多内存

python : Set method attribute from within method

python - 是否可以使用装饰器在 Python 中进行 "extended"时间监控?

haskell - Haskell 中缓存了哪些函数?

java - java中如何计算组合?通过使用内存?

python - 带有复制警告的意外设置