簡體   English   中英

如何在Python中緩存/存儲對象?

[英]How to cache/memoize objects in Python?

我有一些實例化非常慢的對象。 它們代表從外部來源(例如YAML文件)加載的數據,而加載大型YAML文件的速度很慢(我不知道為什么)。

我知道這些對象取決於一些外部因素:

  • 創建對象時傳遞的參數
  • 環境變量
  • 一些外部文件

理想情況下,如果外部因素相同,我希望使用透明的非樣板方法來緩存這些對象:

@cache(depfiles=('foo',), depvars=(os.environ['FOO'],))
class Foo():
    def __init__(*args, **kwargs):
        with open('foo') as fd:
           self.foo = fd.read()
        self.FOO = os.environ['FOO']
        self.args = args
        self.kwargs = kwargs

主要思想是,第一次實例化Foo ,將使用對象的內容創建一個緩存文件,然后在下次實例化(在另一個Python會話中)時,僅當沒有依賴項時才使用該緩存文件。和論點已經改變。

到目前為止,我發現的解決方案是基於shelve

import shelve

class Foo(object):
    _cached = False
    def __new__(cls, *args, **kwargs):
        cache = shelve.open('cache')
        cache_foo = cache.get(cls.__name__)
        if isinstance(cache_foo, Foo):
            cache_foo._cached = True
            return cache_foo
        self = super(Foo, cls).__new__(cls, *args, **kwargs)
        return self

    def __init__(self, *args, **kwargs):
        if self._cached:
            return

        time.sleep(2) # Lots of work
        self.answer = 42

        cache = shelve.open('cache')
        cache[self.__class__.__name__] = self
        cache.sync() 

它可以按原樣完美運行,但是它太樣板了,無法涵蓋所有​​情況:

  • 當不同的類具有相同的名稱時發生沖突
  • 檢查args和kwargs
  • 檢查依賴項(環境變量,外部文件)

是否有任何本機解決方案可在Python中實現類似的行為?

Python 3提供了functools.lru_cache()裝飾器來提供可調用對象的備注,但是我認為您是在要求保留應用程序多次運行的緩存,並且到那時為止,存在各種各樣的不同要求,因此您不太可能找到一個“適合所有人”的解決方案。

如果您自己的答案對您有用,請使用它。 就“太多樣板”而言,我會將緩存提取到一個單獨的mixin類中:在任何情況下, __new__Foo的第一個引用都應該是cls ,並且可以使用__qualname__屬性代替cls.__name__減少類名沖突的可能性(假設Python 3.3或更高版本)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM