python - 内存装饰器保存存储的值

标签 python python-decorators memoization

我有一个如下所示的内存装饰器:

def memoize(obj):
    from functools import wraps
    cache = {}

    @wraps(obj)
    def memoizer(*args, **kwargs):
        if args not in cache:
            cache[args] = obj(*args, **kwargs)
        return cache[args]

    return memoizer

但是,我不确定这个函数是否正常工作,因为在我看来,每次调用装饰函数时它都会将 cache 重新创建为空字典。当我用一个简单的斐波那契函数测试它时,它似乎确实可以正确内存。那么缓存不是每次都会重新创建吗?

python wiki has a version包括这一行:

cache = obj.cache = {}

所以我不确定这是做什么的。我猜想 python 函数是对象,因此它正在创建一个与该函数关联的新属性,并且每次调用该函数时都是公开可用/可用的。

在任一版本中,如果我重复调用该函数(如在递归定义中或仅通过重复调用),那么如何处理缓存?它是否与函数相关联,是否成为“全局”变量,还是其他什么?

最佳答案

1) 每次调用 memoize() 都会创建一个新的缓存。但每个修饰函数仅调用一次 memoize() 。因此,每个修饰函数都有自己的缓存

2) 关于cache = obj.cache = {}:

函数也是 Python 中的对象。正如您已经假设的那样,obj.cache = {} 将在包装函数上创建一个新属性。本地缓存对象和包装函数上的缓存属性将指向同一个字典。

这并不意味着 cache 是一个全局变量 - 它在 memoize 函数中是本地变量,并且是该函数的一个属性。

如果你有一个修饰函数f,你可以在全局范围内访问f.cache(如果这就是你对全局变量的意思)。

如果您重复调用装饰函数,它将始终访问特定于装饰函数的相同缓存


解决内部函数未被“内存”的问题。

def outer():
    # do not add the decorator here!
    def inner():
        return 5
    if(not hasattr(outer, "inner")):
        # the "@" decorator is only syntactical sugar, 
        # we can simply call the decorator function to wrap another function
        outer.inner = memoize( inner )
    outer.inner()
    return outer.inner()

outer()
outer()

关于python - 内存装饰器保存存储的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44577679/

相关文章:

python - 使用 joblib 仅缓存类的某些方法的正确方法

python - numpy rollaxis - 它究竟是如何工作的?

python - scapy 中嗅探功能的过滤器无法正常工作

python - ModuleNotFoundError : No module named 'dnspython'

python - 什么时候调用类装饰器?

python - 对 `lru_cache` 修饰函数使用可变参数可能会出现什么困难?

python - 由角点定义的边界框对象的嵌套属性

python - 相互依赖的模块

algorithm - 内存算法时间复杂度

powershell - 如何在 PowerShell 中内存一个函数?