在给定某些输入 * 的情况下,我使用functools.lru_cache
来提供临时文件路径。但是,如果路径不再存在,我想删除/替换单个对应的密钥。 cache_clear()
方法可能会过大,cache_info()
似乎无济于事。
感谢您的帮助!
* 正在缓存的方法将fileobj从S3流传输到本地临时文件。
答案 0 :(得分:1)
这是通过python.org问题allow to cache_clear(some_key) in lru_cache提出的,遭到拒绝。因此,lru_cache
中没有清除特定条目的方法。
与该问题相关的一个很好的建议是使用名为Foundation for rolling your own LRU cache variants的collections.OrderedDict
实现您自己的变体。
答案 1 :(得分:1)
这是我的解决方案,根据@dmulter的建议,改编自Foundation for rolling your own LRU cache variants。
我添加了inline constexpr char slide_piece = '\42';
并改写了update_wrapper
,以使其更好地用作__repr__
的包装。然后添加一些方法从缓存中删除项目(通过传递与调用它相同的参数),或直接替换缓存中的值(通过传递要替换的值,然后再加上您要使用的相同参数)再次调用func)。我还通过从参数中生成哈希值来为func
添加了一些支持。我还没有对它进行非常彻底的测试,但是它似乎运行得很好。希望这对寻求该功能的下一个人很有用。
我认为应该可以像**kwargs
一样使用它。
@lru_cache
例如
from functools import update_wrapper
class MyLRU:
def __init__(self, func, maxsize=128):
self.cache = collections.OrderedDict()
self.func = func
self.maxsize = maxsize
update_wrapper(self, self.func)
def __call__(self, *args, **kwargs):
cache = self.cache
key = self._generate_hash_key(*args, **kwargs)
if key in cache:
cache.move_to_end(key)
return cache[key]
result = self.func(*args, **kwargs)
cache[key] = result
if len(cache) > self.maxsize:
cache.popitem(last=False)
return result
def __repr__(self):
return self.func.__repr__()
def clear_cache(self):
self.cache.clear()
def cache_remove(self, *args, **kwargs):
"""Remove an item from the cache by passing the same args and kwargs"""
key = self._generate_hash_key(*args, **kwargs)
if key in self.cache:
self.cache.pop(key)
def cache_replace(self, value, *args, **kwargs):
key = self._generate_hash_key(*args, **kwargs)
self.cache[key] = value
@staticmethod
def _generate_hash_key(*args, **kwargs):
key = hash(args)+hash(frozenset(sorted(kwargs.items())))
return key
答案 2 :(得分:0)
使用ring.lru
通过其键控制缓存数据
import ring
@ring.lru()
def f(path):
print('fetching', path)
return 'some contents in ' + path
if __name__ == '__main__':
f('path1')
f('path1') # no print
f.delete('path1')
f('path1') # print again
还有set
或update
可以替换。