Almacene el caché en un archivo functools.lru_cache en Python> = 3.2

Estoy usando @functools.lru_cache en Python 3.3. Me gustaría guardar la memoria caché en un archivo para poder restaurarla cuando se reinicie el progtwig. ¿Cómo podría hacerlo?

Edición 1 Posible solución: Necesitamos encurtir cualquier tipo de llamada

Problema de decapado __closure__ :

 _pickle.PicklingError: Can't pickle : attribute lookup builtins.cell failed 

Si bash restaurar la función sin ella, obtengo:

 TypeError: arg 5 (closure) must be tuple 

No puede hacer lo que quiere usando lru_cache , ya que no proporciona una API para acceder a la memoria caché, y podría reescribirse en C en futuras versiones. Si realmente desea guardar el caché, debe utilizar una solución diferente que le permita acceder al caché.

Es lo suficientemente simple como para escribir un caché a ti mismo. Por ejemplo:

 from functools import wraps def cached(func): func.cache = {} @wraps(func) def wrapper(*args): try: return func.cache[args] except KeyError: func.cache[args] = result = func(*args) return result return wrapper 

Luego puedes aplicarlo como decorador:

 >>> @cached ... def fibonacci(n): ... if n < 2: ... return n ... return fibonacci(n-1) + fibonacci(n-2) ... >>> fibonacci(100) 354224848179261915075L 

Y recuperar el cache :

 >>> fibonacci.cache {(32,): 2178309, (23,): 28657, ... } 

A continuación, puede encoger / deseleccionar el caché como desee y cargarlo con:

 fibonacci.cache = pickle.load(cache_file_object) 

Encontré una solicitud de función en el rastreador de problemas de Python para agregar volcados / cargas a lru_cache , pero no fue aceptada / implementada. Tal vez en el futuro sea posible tener soporte integrado para estas operaciones a través de lru_cache .

Considere el uso de joblib.Memory para el almacenamiento en caché persistente en el disco.

Dado que el disco es enorme, no hay necesidad de un esquema de almacenamiento en caché LRU.

Puedes usar una biblioteca mía, mezmorizar

 import random from mezmorize import Cache cache = Cache(CACHE_TYPE='filesystem', CACHE_DIR='cache') @cache.memoize() def add(a, b): return a + b + random.randrange(0, 1000) >>> add(2, 5) 727 >>> add(2, 5) 727 

Se supone que no debe tocar nada dentro de la implementación del decorador, excepto la API pública, por lo que si desea cambiar su comportamiento, probablemente necesite copiar su implementación y agregar las funciones necesarias. Tenga en cuenta que la memoria caché se almacena actualmente como una lista circular doblemente vinculada, por lo que deberá tener cuidado al guardarla y cargarla.