I'm exploiting the cachetools @ttl_cache
decorator (not @cached
). I need to ignore some params in the cache key. E.g,.
@ttl_cache(maxsize=1024, ttl=600)
def my_func(foo, ignore_bar, ignore_baz):
# do stuff
Working that way, I get this:
>>> my_func("foo", "ignore_bar", "ignore_baz") # cache miss
>>> my_func("foo", "ignore_bar", "ignore_baz") # cache hit
>>> my_func("foo", "ignore_bar_bar", "ignore_baz_baz") # cache miss!
What I need:
>>> my_func("foo", "ignore_bar", "ignore_baz") # cache miss
>>> my_func("foo", "ignore_bar", "ignore_baz") # cache hit
>>> my_func("foo", "ignore_bar_bar", "ignore_baz_baz") # cache hit!!!!!
Is there a way to get that using @ttl_cache
?
CodePudding user response:
I haven't used cachetools, but I've looked at the docs out of interest. Apparently, there's no built-in way. If you really need this functionality, I can suggest a hack like the following:
class PackedArgs(tuple):
def __hash__(self):
return hash(self[0])
def __eq__(self, other):
if isinstance(other, self.__class__):
return self[0] == other[0]
else:
return NotImplemented
def pack_args(func):
def inner(packed_args):
return func(*packed_args)
return inner
def unpack_args(func):
def inner(*args):
return func(PackedArgs(args))
return inner
@unpack_args
@ttl_cache(maxsize=1024, ttl=600)
@pack_args
def my_func(foo, ignore_bar, ignore_baz):
# do stuff
Essentially: "pack" your function's arguments to a single tuple-like object that hashes as it's 0th element and causes @ttl_cache
to behave like you need. Then, "unpack" them to restore the normal interface and avoid actually having to pass this one big argument when calling.
Please note that this is just a (very hacky) concept, I haven't tested this code at all. It probably won't work as is.
By the way, your requirement sounds interesting. You can submit it to cachetools as a feauture request and link this thread. I can imagine it being implemented as something like a key=
kwarg lambda, similar to builtin sort
's.
CodePudding user response:
Well, that's exactly what @cached
and its custom key
argument are for, so I wonder why you want to use @ttl_cache
for this:
from cachetools import TTLCache, cached
from cachetools.keys import hashkey
def mykey(foo, ignore_bar, ignore_baz):
return hashkey(foo)
@cached(cache=TTLCache(maxsize=1024, ttl=600), key=mykey)
def my_func(foo, ignore_bar, ignore_baz):
# do stuff