如何使用 cachetools ttl_cache 忽略函数参数
How to ignore function arguments with cachetools ttl_cache
我正在利用 cachetools @ttl_cache
装饰器(不是 @cached
)。我需要忽略缓存键中的一些参数。例如,.
@ttl_cache(maxsize=1024, ttl=600)
def my_func(foo, ignore_bar, ignore_baz):
# do stuff
以这种方式工作,我明白了:
>>> 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!
我需要的:
>>> 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!!!!!
有没有办法使用 @ttl_cache
获得它?
我没有使用过 cachetools,但我出于兴趣查看了文档。显然,没有内置的方法。如果您真的需要此功能,我可以建议您使用如下黑客方法:
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
本质上:将您的函数的参数“打包”到一个类似元组的对象,该对象散列为第 0 个元素并导致 @ttl_cache
的行为符合您的需要。然后,“解压”它们以恢复正常界面,并避免在调用时实际必须传递这一大参数。
请注意,这只是一个(非常老套的)概念,我根本没有测试过这段代码。它可能不会像现在这样工作。
顺便说一句,你的要求听起来很有趣。您可以将其作为功能请求提交给 cachetools,并 link 此线程。我可以想象它被实现为类似于 key=
kwarg lambda 的东西,类似于内置的 sort
。
嗯,这正是 @cached
及其自定义 key
参数的用途,所以我想知道您为什么要为此使用 @ttl_cache
:
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
我正在利用 cachetools @ttl_cache
装饰器(不是 @cached
)。我需要忽略缓存键中的一些参数。例如,.
@ttl_cache(maxsize=1024, ttl=600)
def my_func(foo, ignore_bar, ignore_baz):
# do stuff
以这种方式工作,我明白了:
>>> 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!
我需要的:
>>> 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!!!!!
有没有办法使用 @ttl_cache
获得它?
我没有使用过 cachetools,但我出于兴趣查看了文档。显然,没有内置的方法。如果您真的需要此功能,我可以建议您使用如下黑客方法:
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
本质上:将您的函数的参数“打包”到一个类似元组的对象,该对象散列为第 0 个元素并导致 @ttl_cache
的行为符合您的需要。然后,“解压”它们以恢复正常界面,并避免在调用时实际必须传递这一大参数。
请注意,这只是一个(非常老套的)概念,我根本没有测试过这段代码。它可能不会像现在这样工作。
顺便说一句,你的要求听起来很有趣。您可以将其作为功能请求提交给 cachetools,并 link 此线程。我可以想象它被实现为类似于 key=
kwarg lambda 的东西,类似于内置的 sort
。
嗯,这正是 @cached
及其自定义 key
参数的用途,所以我想知道您为什么要为此使用 @ttl_cache
:
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