2014-04-30 30 views
2

我正在實現一個小的「持久」版本functools.lru_cache,其中「持久」意味着緩存不會在後續運行之間被破壞。爲此,我認爲我可以簡單地將functools.lru_cache所使用的字典替換爲shelve對象,但我正在運行對密鑰的要求是str。我試圖通過使用str(hash(...).to_int(...))來修復它,但hash(...)對於cpython解釋器的不同運行之間的相同對象是不同的。持久字典,其中密鑰可以是任何可哈希

是否有像shelve這樣的類允許任何可哈希鍵,而不僅僅是,而像字典一樣可以透明地訪問?

一些細節:我的緩存可能在100MB左右。它有點頻繁閱讀,而且很少寫。

+0

一個問題在我的腦海裏出現,爲什麼不把你的密鑰'str()'串起來? – zeapo

+2

@zeapo在'str(bytes(hash(...)。to_int(...)))'?我在發佈這個問題後想到了這個問題。它在內部傷害了我,雖然;-) – gerrit

+0

@zeapo只是意識到'散列(...)'不同的cpython運行之間不一致。 – gerrit

回答

0

可以繼承Shelf你想要的方式嗎?

from shelve import Shelf 

class SubShelf(Shelf): 
    def __init__(self): 
     super().__init__() 

    def __setitem__(self, key, val): 
     h = str(hash(key)) 
     super().__setitem__(h, val) 

    def __getitem__(self, key): 
     h = str(hash(key)) 
     return super().__getitem__(h) 
+0

這不起作用,因爲'hash(key)'在Python解釋器的後續運行之間對於相同的鍵不相同。 – gerrit

1

具體的解決方案實際上取決於你的需求,但很可能你會發現,使用一個數據庫是您最好的解決方案。您也可以使用pickle而不是擱置,但這當然有其不利之處。

  • 是緩存大嗎?

那麼你需要一個解決方案,避免在每個訪問(例如基於pickle的解決方案)上讀取/寫入整個緩存。一個DB。

  • 是否經常訪問?

那麼你可能也想要一個內存中的緩存來避免頻繁的緩慢的外部訪問。

快速谷歌搜索發現這個:persistentdict

另請參閱this question

+0

大多數(即使不是全部)數據庫仍然不需要密鑰是字符串嗎? – gerrit

相關問題