2 回答

TA貢獻1829條經驗 獲得超9個贊
這里有幾個選項。一種是使用臨時文件作為緩存的持久存儲,并在每次加載模塊時嘗試加載:
# 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

TA貢獻1847條經驗 獲得超7個贊
由于重新加載的全部目的是確保執行的模塊的代碼第二次運行,因此基本上無法避免某種“重新加載檢測”。
您使用的代碼似乎是您參考的問題中給出的最佳答案。
添加回答
舉報