How can I make @functools.lru_cache
decorator ignore some of the function arguments with regard to caching key?
For example, I have a function that looks like this:
def find_object(db_handle, query): # (omitted code) return result
If I apply lru_cache
decorator just like that, db_handle
will be included in the cache key. As a result, if I try to call the function with the same query
, but different db_handle
, it will be executed again, which I'd like to avoid. I want lru_cache
to consider query
argument only.
With cachetools you can write:
from cachetools import cached from cachetools.keys import hashkey from random import randint @cached(cache={}, key=lambda db_handle, query: hashkey(query)) def find_object(db_handle, query): print("processing {0}".format(query)) return query queries = list(range(5)) queries.extend(range(5)) for q in queries: print("result: {0}".format(find_object(randint(0, 1000), q)))
I have at least one very ugly solution. Wrap db_handle
in a object that's always equals, and unwrap it inside the function.
It requires a decorator with quite a bit of helper functions, which makes stack trace quite confusing.
class _Equals(object): def __init__(self, o): self.obj = o def __eq__(self, other): return True def __hash__(self): return 0 def lru_cache_ignoring_first_argument(*args, **kwargs): lru_decorator = functools.lru_cache(*args, **kwargs) def decorator(f): @lru_decorator def helper(arg1, *args, **kwargs): arg1 = arg1.obj return f(arg1, *args, **kwargs) @functools.wraps(f) def function(arg1, *args, **kwargs): arg1 = _Equals(arg1) return helper(arg1, *args, **kwargs) return function return decorator
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With