以前の記事で、functools.cache をそのままメソッドに使うとメモリリークになることと、その回避方法をいくつか紹介しました。
最後に紹介していた方法がこれです。
from functools import cache class A: def __init__(self, x): self._x = x self.f = cache(self._f) def _f(self, y): return self._x * y
このコードでは A.f() が呼ばれていない時も cache(self._f) が実行されているので、 cached_property を使えばさらに改善ができます。
from functools import cache, cached_property class A: def __init__(self, x): self._x = x @cached_property def f(self): return cache(self._f) def _f(self, y): return self._x * y
しかしキャッシュが必要になるたびにこのコードを書くのは面倒ですよね。それをしてくれるのが cached_method です。
uv add cached_method でインストールできます。上の例に cached_method を使うとこうなります。
from cached_method import cached_method class A: def __init__(self, x): self._x = x @cached_method def f(self, y): return self._x * y
メソッドのためのcacheでコレータとしては cachetools の cachedmethod もありましたが、実装が functools.lru_cache と異なるものになるし、メソッドごとにキャッシュのdictとそれを取得するための関数を用意する必要があり面倒でした。一方で typing サポートは cachetools の方がstubがあるので痛し痒しといったところです。