Reputation: 17352
This is a skeleton of the function I want to enhance with a cache, because doing RPC (remote procedure call) involves a TCP connection to other host.
def rpc(rpc_server, rpc_func, arg):
return rpc_server.do_rpc(rpc_func, arg)
However, the most convenient way of simply decorating it with:
@functools.lru_cache()
does not work well, beacuse rpc_server
objects come and go and this parameter should be ignored by the cache.
I can write a simple memoizing code myself. No problem with that. Actually, I see no other solution.
I am unable to rewrite this function in such way that @lru_cache()
decorator can be applied and rpc_server
will be passed as an argument (i.e. I don't want to make rpc_server
a global variable). Is it possible?
Upvotes: 13
Views: 5396
Reputation: 17352
I'm posting this just for completness. Comments are welcome, but please do not vote.
I have found a way how to satisfy the conditions from my question. I'm not going to use this code. But it shows how flexible Python is.
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
Upvotes: 16