Вот несколько вариантов.Одним из них является использование временного файла в качестве постоянного хранилища для вашего кэша и попытка загрузки при каждой загрузке модуля:
# foo.py
import tempfile
import pathlib
import pickle
_CACHE_TEMP_FILE_NAME = '__foo_cache__.pickle'
_CACHE = {}
def expensive(x):
try:
return _CACHE[x]
except KeyError:
# do a lot of work
_CACHE[x] = res
_save_cache()
return res
def _save_cache():
tmp = pathlib.Path(tempfile.gettempdir(), _CACHE_TEMP_FILE_NAME)
with tmp.open('wb') as f:
pickle.dump(_CACHE, f)
def _load_cache():
global _CACHE
tmp = pathlib.Path(tempfile.gettempdir(), _CACHE_TEMP_FILE_NAME)
if not tmp.is_file():
return
try:
with tmp.open('rb') as f:
_CACHE = pickle.load(f)
except pickle.UnpicklingError:
pass
_load_cache()
Единственная проблема, связанная с этим, заключается в том, что вам нужно доверять среде, а не писатьчто-либо вредоносное вместо временного файла (модуль pickle
не защищен от ошибочных или вредоносных данных).
Другой вариант - использовать другой модуль для кэша, который не перезагружается:
# foo_cache.py
Cache = {}
А потом:
# foo.py
import foo_cache
def expensive(x):
try:
return foo_cache.Cache[x]
except KeyError:
# do a lot of work
foo_cache.Cache[x] = res
return res