You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据Python函数返回值控制缓存,不缓存返回None的调用结果

Python 实现仅缓存非指定值的lru_cache方案

方案1:通用自定义条件缓存装饰器(Python 3.9+)

该方案完全兼容原生functools.lru_cache的所有参数,可自定义配置不需要缓存的返回值列表:

from functools import lru_cache, wraps

def conditional_lru_cache(exclude_values=(None,), **lru_kwargs):
    cache_decorator = lru_cache(**lru_kwargs)
    def decorator(func):
        wrapped = cache_decorator(func)
        @wraps(func)
        def inner(*args, **kwargs):
            result = wrapped(*args, **kwargs)
            # 返回值属于排除列表时删除本次缓存
            if result in exclude_values:
                wrapped.cache_delete(*args, **kwargs)
            return result
        # 透传原生lru_cache的管理方法
        inner.cache_info = wrapped.cache_info
        inner.cache_clear = wrapped.cache_clear
        inner.cache_delete = wrapped.cache_delete
        return inner
    return decorator

使用方式和原生装饰器一致:

@conditional_lru_cache(maxsize=128, exclude_values=(None,))
def my_fun(link):
    res = fetch_data(link)
    return res

方案2:Python 3.9以下兼容版本

3.9版本才新增cache_delete方法,低版本可通过操作缓存的底层字典实现相同效果:

from functools import lru_cache, wraps, _make_key

def conditional_lru_cache(exclude_values=(None,), **lru_kwargs):
    cache_decorator = lru_cache(**lru_kwargs)
    def decorator(func):
        wrapped = cache_decorator(func)
        typed = lru_kwargs.get('typed', False)
        @wraps(func)
        def inner(*args, **kwargs):
            # 手动构造缓存key
            key = _make_key(args, kwargs, typed=typed)
            result = wrapped(*args, **kwargs)
            if result in exclude_values:
                wrapped.cache.pop(key, None)
            return result
        inner.cache_info = wrapped.cache_info
        inner.cache_clear = wrapped.cache_clear
        return inner
    return decorator

极简临时方案

如果仅需要单次使用,不想封装装饰器,也可以直接手动控制缓存:

from functools import lru_cache

# 先初始化缓存装饰器
cached_fetch = lru_cache(maxsize=128)(fetch_data)

def my_fun(link):
    res = cached_fetch(link)
    if res is None:
        # 无效结果直接删除缓存
        cached_fetch.cache_delete(link)
    return res

补充说明:如果使用Python 3.9+的functools.cache(无大小限制的lru_cache),只需要把上述代码中的lru_cache替换为cache即可实现相同逻辑,也支持自定义排除值。

内容的提问来源于stack exchange,提问作者sophros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 20:39:03