Pythonでfunctools.cached_property を使ってキャッシュプロパティを定義 (Python 3.8以降)
この記事では、Python 3.8以降で導入されたfunctools.cached_propertyデコレータを使用して、プロパティの値をキャッシュする方法について説明します。パフォーマンスの最適化に役立つこのテクニックを、具体的な例を通して学びます。
目次
cached_propertyの概要
functools.cached_propertyは、プロパティの値を一度計算したらキャッシュし、次回以降はキャッシュされた値を返すデコレータです。プロパティの計算に時間がかかる場合や、同じ値が何度も必要となる場合に、パフォーマンスを大幅に向上させることができます。
Python 3.8以降で標準ライブラリに含まれています。
from functools import cached_property
class MyClass:
def __init__(self, value):
self._value = value
@cached_property
def expensive_property(self):
print("expensive_property is calculated...")
# 計算コストの高い処理
return self._value * 2
基本的な使用方法
cached_propertyデコレータをメソッドの前に付けるだけです。
from functools import cached_property
class MyClass:
@cached_property
def my_property(self):
return 'Hello, cached_property!'
利点と注意点
利点
- プロパティの値をキャッシュすることで、計算コストの高い処理を何度も実行する必要がなくなり、パフォーマンスが向上する。
- 一度計算された値は、インスタンスのライフサイクルの間、キャッシュされる。
注意点
- プロパティの値が変更される可能性がある場合は、注意が必要。キャッシュされた値が古くなる可能性がある。
- キャッシュされた値は、インスタンスのライフサイクルの間、常に同じ値となる。値を変更したい場合は、@propertyとsetterメソッドを組み合わせる必要がある。
- あまりにも頻繁にアクセスするプロパティには、別のキャッシュメカニズム(例えば、`lru_cache`)の方が効率的である可能性がある。
実践例:ファイル読み込み
大きなファイルを読み込むプロパティを定義してみましょう。
import os
from functools import cached_property
class FileProcessor:
def __init__(self, filepath):
self.filepath = filepath
@cached_property
def file_content(self):
print(f"Reading file: {self.filepath}")
with open(self.filepath, 'r') as f:
return f.read()
# テスト
filepath = 'my_file.txt'
with open(filepath, 'w') as f:
f.write('This is a test file.')
processor = FileProcessor(filepath)
print(processor.file_content)
print(processor.file_content) # キャッシュされた値が返される
上記のように、ファイルを読み込む処理は一度だけ実行され、2回目のアクセスではキャッシュされた値が返されます。ファイルサイズが大きい場合、この効果は顕著に現れます。