如何通过一个参数部分删除functools.lru\u缓存?

2024-04-29 07:39:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个get(bid, mid, pid)函数。它用lru_cache装饰。例如,我想删除带有bid == 105的所有缓存项

我在考虑一些闭包,它返回装饰过的函数。然后我为每个bid条目获得一些单独的缓存,并使用这些闭包的dict获得非缓存函数,这些闭包的作用类似于路由器。但也许有一种更像Python的方法

upd:我想出了这样的办法,而且似乎奏效了

getters = {}
def facade(bid, mid, pid):
    global getters             # not very good, better to use class

    if not bid in getters:
        def create_getter(bid):
            @functools.lru_cache(maxsize=None)
            def get(mid, pid):
                print ('cache miss')
                return bid + mid + pid
            return get
        getters[bid] = create_getter(bid)

    return getters[bid](mid, pid)

val = facade(bid, mid, pid)   # ability to read like before
if need_to_drop:
    getters[bid].cache_clear()  # ability to flush entries with specified bid

Tags: to函数cachegetreturnifdefnot
1条回答
网友
1楼 · 发布于 2024-04-29 07:39:59

也许包装functools.lru_cache和过滤参数

from functools import lru_cache


def filtered_lru(filter_func: callable, maxsize: int):
    def wrapper(f):
        cached = lru_cache(maxsize=maxsize)(f)

        def wrapped(*args, **kwargs):
            if filter_func(*args, **kwargs):
                print('Using cache')
                return cached(*args, **kwargs)
            else:
                print('Not using cache')
                return f(*args, **kwargs)

        return wrapped

    return wrapper


def _get_filter(*args, **kwargs):
    return args[0] != 0


@filtered_lru(_get_filter, maxsize=100)
def get(num):
    print('Calculating...')
    return 2 * num


if __name__ == '__main__':
    print(get(1))
    print(get(1))
    print(get(1))
    print(get(0))
    print(get(0))

输出:

Using cache
Calculating...
2
Using cache
2
Using cache
2
Not using cache
Calculating...
0
Not using cache
Calculating...
0

相关问题 更多 >