Ostatnio przejrzałem istniejącą bazę kodu zawierającą wiele klas, w których atrybuty instancji odzwierciedlają wartości przechowywane w bazie danych. Przefaktoryzowałem wiele z tych atrybutów, aby ich wyszukiwanie w bazie danych zostało odroczone, tj. nie być inicjalizowane w konstruktorze, ale tylko przy pierwszym czytaniu. Te atrybuty nie zmieniają się przez cały okres istnienia instancji, ale są prawdziwym wąskim gardłem w obliczaniu tego pierwszego razu i są dostępne tylko w specjalnych przypadkach. W związku z tym mogą być również buforowane po ich pobraniu z bazy danych (dlatego pasuje to do definicji memoizacji, w której dane wejściowe to po prostu „brak danych wejściowych”).
W kółko wpisuję następujący fragment kodu dla różnych atrybutów w różnych klasach:
class testA(object):
def __init__(self):
self._a = None
self._b = None
@property
def a(self):
if self._a is None:
# Calculate the attribute now
self._a = 7
return self._a
@property
def b(self):
#etc
Czy istnieje już dekorator, który może to zrobić w Pythonie, o którym po prostu nie wiem? A może istnieje dość prosty sposób na zdefiniowanie dekoratora, który to robi?
Pracuję pod Pythonem 2.5, ale odpowiedzi 2.6 mogą nadal być interesujące, jeśli są znacząco różne.
Uwaga
To pytanie zostało zadane, zanim Python zawierał wiele gotowych dekoratorów do tego. Zaktualizowałem go tylko pod kątem poprawnej terminologii.
functools.lru_cache().