CodeWalk

自定义缓存装饰器(TTL过期/LRU/文件持久化)

作者:我还是少年 · 2026-05-30 12:55

请展示如何实现一个支持TTL过期时间的自定义缓存装饰器、一个基于磁盘的文件缓存装饰器,以及一个带最大大小限制的LRU缓存装饰器。对比functools内置缓存和自定义缓存的优缺点。

回答

我还是少年

1. TTL过期缓存

import time
from functools import wraps

def ttl_cache(seconds=60):
    def decorator(func):
        cache = {}
        @wraps(func)
        def wrapper(*args, **kwargs):
            key = args + tuple(sorted(kwargs.items()))
            now = time.time()
            if key in cache and now - cache[key][1] < seconds:
                return cache[key][0]
            result = func(*args, **kwargs)
            cache[key] = (result, now)
            return result
        wrapper.cache = cache
        return wrapper
    return decorator

@ttl_cache(seconds=30)
def get_user(user_id):
    return db.query(f'SELECT * FROM users WHERE id={user_id}')

2. 文件缓存装饰器

import json
import os
from functools import wraps

def file_cache(cache_dir='/tmp/cache'):
    os.makedirs(cache_dir, exist_ok=True)
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            key = f'{func.__name__}_{hash(args)}_{hash(tuple(kwargs.items()))}'
            cache_path = os.path.join(cache_dir, f'{key}.json')
            if os.path.exists(cache_path):
                with open(cache_path) as f:
                    return json.load(f)
            result = func(*args, **kwargs)
            with open(cache_path, 'w') as f:
                json.dump(result, f)
            return result
        return wrapper
    return decorator

3. 大小受限LRU缓存

from collections import OrderedDict

def lru_cache_custom(maxsize=128):
    def decorator(func):
        cache = OrderedDict()
        @wraps(func)
        def wrapper(*args, **kwargs):
            key = args + tuple(sorted(kwargs.items()))
            if key in cache:
                cache.move_to_end(key)
                return cache[key]
            result = func(*args, **kwargs)
            cache[key] = result
            if len(cache) > maxsize:
                cache.popitem(last=False)
            return result
        return wrapper
    return decorator

对比

特性functools内置自定义
TTL过期不支持支持
文件持久化不支持支持
分布式缓存不支持支持
线程安全不支持可选
开发维护零成本需自测

**建议:**多数场景用内置lru_cache/cache;需要TTL/持久化时用cachetools库或自定义。