如何在functools.lru_cache中忽略一个参数?

12

这是我想用缓存增强的函数的框架,因为执行RPC(远程过程调用)需要与其他主机建立TCP连接。

def rpc(rpc_server, rpc_func, arg):
    return rpc_server.do_rpc(rpc_func, arg)

然而,最简单的方法是仅用以下方式来装饰它:

@functools.lru_cache()

不起作用,因为rpc_server对象会不断地出现和消失,而且缓存应该忽略这个参数。

我可以自己编写一个简单的记忆化代码。这没问题。实际上,我没有看到其他解决方法。

我无法以这样的方式重写此函数,即可以应用@lru_cache()装饰器rpc_server作为参数传递(即,我不想将rpc_server变成全局变量)。这可能吗?


1
不,我不认为可以比自己编写更简单地完成这种部分记忆化。 - jonrsharpe
1个回答

15

我发布这个帖子只是为了完整性。欢迎留言,但请不要投票。


我找到了一种方法来满足我问题中的条件。我不打算使用这段代码。但它展示了Python的灵活性。

import functools

class BlackBox:
    """All BlackBoxes are the same."""
    def __init__(self, contents):
        # TODO: use a weak reference for contents
        self._contents = contents

    @property
    def contents(self):
        return self._contents

    def __eq__(self, other):
        return isinstance(other, type(self))

    def __hash__(self):
        return hash(type(self))

@functools.lru_cache()
def _cached_func(blackbox, real_arg):
    print("called with args:", blackbox.contents, real_arg)
    return real_arg + 1000

def cached_func(ignored_arg, real_arg):
    # ignored means ignored by the cache
    return _cached_func(BlackBox(ignored_arg), real_arg)

cached_func("foo", 1) # cache miss
cached_func("bar", 1) # cache hit

cached_func("bar", 2) # cache miss
cached_func("foo", 2) # cache hit

为什么要请求人们不要投票,而且为什么你自己没有使用这个解决方案?我喜欢这个解决方案!你感觉它有什么问题吗?对我来说,它似乎是完美的解决方案。 - John Bowers
1
@JohnBowers 我在网上和这里的SO找到了该代码。任何功劳(投票)应归原作者所有,而不是我。如果我记得正确,原始任务已被修改,我不需要解决方案。它与代码无关。如果看起来有问题,我很抱歉。我不是母语为英语的人,经常无法清楚地表达自己。 - VPfB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接