ここにあるLRUキャッシュデコレータの使用: http://code.activestate.com/recipes/578078-py26-and-py30-backport-of-python-33s-lru-cache/
from lru_cache import lru_cache
class Test:
@lru_cache(maxsize=16)
def cached_method(self, x):
return x + 5
これで装飾されたクラスメソッドを作成できますが、最終的にはクラスTestのallインスタンスに適用されるグローバルキャッシュが作成されます。ただし、私の意図は、インスタンスごとのキャッシュを作成することでした。したがって、3つのテストをインスタンス化する場合、3つのインスタンスすべてに対して1つのLRUキャッシュではなく、3つのLRUキャッシュがあります。
これが発生していることを示す唯一の兆候は、異なるクラスインスタンスで装飾されたメソッドでcache_info()を呼び出すと、すべて同じキャッシュ統計が返されます(非常に異なる引数と相互作用しているため、発生する可能性は非常に低いです)。
CacheInfo(hits=8379, misses=759, maxsize=128, currsize=128)
CacheInfo(hits=8379, misses=759, maxsize=128, currsize=128)
CacheInfo(hits=8379, misses=759, maxsize=128, currsize=128)
このデコレータに各クラスインスタンスのキャッシュを簡単に作成させるデコレータまたはトリックはありますか?
コードを変更したくないと仮定します(たとえば、3.3に移植して、stdlibを使用できるようにしたいため functools.lru_cache
、または functools32
レシピをコピーしてコードに貼り付ける代わりにPyPIから)、1つの明白な解決策があります:各インスタンスで新しい装飾されたインスタンスメソッドを作成します。
class Test:
def cached_method(self, x):
return x + 5
def __init__(self):
self.cached_method = lru_cache(maxsize=16)(self.cached_method)
最近では、methodtools
が機能します
from methodtools import lru_cache
class Test:
@lru_cache(maxsize=16)
def cached_method(self, x):
return x + 5
Methodtoolsをインストールする必要があります
pip install methodtools
まだpy2を使用している場合は、functools32も必要です
pip install functools32
これはどうですか:methodをlru_cache
でラップするfunctionデコレータ各インスタンスで初めて呼び出されますか?
def instance_method_lru_cache(*cache_args, **cache_kwargs):
def cache_decorator(func):
@wraps(func)
def cache_factory(self, *args, **kwargs):
print('creating cache')
instance_cache = lru_cache(*cache_args, **cache_kwargs)(func)
instance_cache = instance_cache.__get__(self, self.__class__)
setattr(self, func.__name__, instance_cache)
return instance_cache(*args, **kwargs)
return cache_factory
return cache_decorator
次のように使用します。
class Foo:
@instance_method_lru_cache()
def times_2(self, bar):
return bar * 2
foo1 = Foo()
foo2 = Foo()
print(foo1.times_2(2))
# creating cache
# 4
foo1.times_2(2)
# 4
print(foo2.times_2(2))
# creating cache
# 4
foo2.times_2(2)
# 4
GitHubの要点です いくつかのインラインドキュメントがあります。