[英]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()
它可以按原樣完美運行,但是它太樣板了,無法涵蓋所有情況:
是否有任何本機解決方案可在Python中實現類似的行為?
Python 3提供了functools.lru_cache()
裝飾器來提供可調用對象的備注,但是我認為您是在要求保留應用程序多次運行的緩存,並且到那時為止,存在各種各樣的不同要求,因此您不太可能找到一個“適合所有人”的解決方案。
如果您自己的答案對您有用,請使用它。 就“太多樣板”而言,我會將緩存提取到一個單獨的mixin類中:在任何情況下, __new__
對Foo
的第一個引用都應該是cls
,並且可以使用__qualname__
屬性代替cls.__name__
減少類名沖突的可能性(假設Python 3.3或更高版本)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.