The answer is going to depend a lot on how expensive it is to perform the calculation and how often you call it compared each time the inputs are updated.
If the calculation is cheap or you are calling it exactly once for each time that the inputs are updated, then it will be convenient to implement it as a property, so that it is calculated on-the-fly when it is needed. (See Thierry Lathuille's answer for implementation details.)
However, if it is expensive to calculate and you might call it repeatedly without changing the inputs (here, var1
and var2
), then your options are:
To add it as an explicit attribute (alongside var1
and var2
) and perform the calcuation inside your increment
method.
To use the cached property package, and then inside your increment
method you force invalidation of the cache, (i.e. del self.__dict__['added_vars']
), so that next time that the property is accessed it will be recalculated, but otherwise the cache will be used for repeated accesses. This has the advantage that you recalculate it only exactly as often as needed.
Note that cached-property
is outside the standard library, but if you prefer not to install additional packages, you could also implement a cache yourself. For example:
class Example:
def __init__(self):
self.var1 = 0
self.var2 = 0
def increment(self):
self.var1 += 1
self.var2 += 1
try:
del self._added_vars
except AttributeError:
pass
@property
def added_vars(self):
try:
return self._added_vars
except AttributeError:
print("recalculating")
self._added_vars = self.var1 + self.var2
return self._added_vars
def __repr__(self):
return str(self.added_vars)
ex = Example()
print(ex)
ex.increment()
print(ex)
print(ex)
Gives:
recalculating
0
recalculating
2
2