Python

Cache disque en décorateur avec statistiques hit/miss

Décorateur qui mémorise les retours de fonction en JSON sur disque (clé SHA-1 des arguments), survit aux redémarrages contrairement à lru_cache, et trace les hits/miss.

Cas d'usage

Économiser les quotas d'une API payante entre deux exécutions d'un script de reporting quotidien.

Prérequis

Python 3.9+ (bibliothèque standard)

Python
import functools
import hashlib
import json
import time
from pathlib import Path

CACHE = Path(".cache")
CACHE.mkdir(exist_ok=True)
stats = {"hit": 0, "miss": 0}

def cache_disque(fn):
    @functools.wraps(fn)
    def wrapper(*args):
        cle = hashlib.sha1(json.dumps([fn.__name__, args]).encode()).hexdigest()
        fichier = CACHE / f"{cle}.json"
        if fichier.exists():
            stats["hit"] += 1
            return json.loads(fichier.read_text())
        stats["miss"] += 1
        resultat = fn(*args)
        fichier.write_text(json.dumps(resultat))
        return resultat
    return wrapper

@cache_disque
def taux_change(devise):
    time.sleep(1.2)                  # simule un appel API lent et payant
    return {"USD": 1.085, "GBP": 0.842}[devise]

t0 = time.perf_counter()
for d in ["USD", "GBP", "USD", "USD", "GBP"]:
    taux_change(d)
print(f"5 appels en {time.perf_counter() - t0:.2f} s "
      f"— hits : {stats['hit']}, miss : {stats['miss']}")
print(f"entrées en cache : {len(list(CACHE.glob('*.json')))}")

Résultat

5 appels en 2.41 s — hits : 3, miss : 2
entrées en cache : 2

# 2e exécution du script (cache chaud) :
5 appels en 0.00 s — hits : 5, miss : 0
entrées en cache : 2
CacheDécorateurhashlibPerformance

Snippets liés

Retour au Data Lab