Reputation: 701
I'm trying to use the result of a class method several times without doing the heavy calculations required to obtain the result.
I am seeing the following options. Which ones do you think is the right one, or more pythonic?
What are the advantages and disadvantages of each one?
class Test:
def __init__(self, *args):
# do stuff
@property
def new_method(self):
try:
return self._new_property
except AttributeError:
# do some heavy calculations
return self._new_property
from functools import lru_cache
class Test:
def __init__(self, *args):
# do stuff
@property
@lru_cache()
def new_method(self):
# do some heavy calculations
return self._new_property
from django.utils.functional import cached_property
class Test:
def __init__(self, *args):
# do stuff
@cached_property
def new_method(self):
# do some heavy calculations
return self._new_property
Upvotes: 14
Views: 3411
Reputation: 136347
Python 3.8 update: You can now use functools.cached_property
from functools import cached_property
class Test:
def __init__(self, *args):
# do stuff
@cached_property
def new_method(self):
# do some heavy calculations
return self._new_property
Upvotes: 14
Reputation: 948
Try/except is simple and readable, but one day you would want to cache another property, right? So one day you will write your own cached property probably.
lru_cache it is a good idea to use standard library, but as you don't need lru cache, it is an overhead probably.
Django's cache_property works exactly as you want and it is pretty simple. It has analogue in werkzeug (so Flask users familiar with it too), it is easy to find a sources, so probably it is a good choice for you.
Upvotes: 4