I\'m writing a class in python and I have an attribute that will take a relatively long time to compute, so I only want to do it once. Also, it will not be
Python ≥ 3.8 @property and @functools.lru_cache have been combined into @cached_property.
import functools
class MyClass:
@functools.cached_property
def foo(self):
print("long calculation here")
return 21 * 2
Python ≥ 3.2 < 3.8
You should use both @property and @functools.lru_cache decorators:
import functools
class MyClass:
@property
@functools.lru_cache()
def foo(self):
print("long calculation here")
return 21 * 2
This answer has more detailed examples and also mentions a backport for previous Python versions.
Python < 3.2
The Python wiki has a cached property decorator (MIT licensed) that can be used like this:
import random
# the class containing the property must be a new-style class
class MyClass(object):
# create property whose value is cached for ten minutes
@cached_property(ttl=600)
def randint(self):
# will only be evaluated every 10 min. at maximum.
return random.randint(0, 100)
Or any implementation mentioned in the others answers that fits your needs.
Or the above mentioned backport.