缓存方法的结果

时间:2018-04-24 10:32:40

标签: python python-2.7 caching

对于项目,我想缓存一个方法计算的结果。 一些约束:

  • 我不能使用Python3
  • 我无法使用第三方模块

我到目前为止所得到的是:

def cached_method(fun):
    """A memoize decorator for class methods."""
    @functools.wraps(fun)
    def get(self, *args, **kwargs):
        """Return the value if cached.
        Get it, cache it and return it if not.
        """
        try:
            self._cache[fun]
        except AttributeError:
            self._cache = {}
        except KeyError:
            pass

        return self._cache.setdefault(fun, {}).setdefault((args, tuple(kwargs.items())), fun(self, *args, **kwargs))

    return get

然而,出了点问题。事实上,使用一个最小的例子,例如:

class TestClass(object):

    @cached_method
    def method(self, p_arg):
        print 'sentinel'
        return p_arg

sut = TestClass()
sut.method(2)
sut.method(2)

你会看到方法被调用两次('sentinel'被打印两次)

通过PDB检查我无法看到问题是什么,因为第二次_cache实际上包含了所有需要的内容。

修改

正如评论中指出的那样,问题在于setdefault,无论密钥是否被找到,它都会调用默认传递的参数(第二个)。

要解决此问题,请将以上return行替换为:

results = self.cache.setdefault(fun, {})

try:
    ret = results[(args, tuple(kwargs.items()))]
except KeyError:
    ret = results[(args, tuple(kwargs.items()))] = fun(self, *args, **kwargs)

return ret

0 个答案:

没有答案