I have a class which caches some values to avoid computing them many times, for instance
class A(object):
def __init__(self, a, b):
self.a = a
self.b = b
self._value = None
@property
def value(self):
if self._value is None:
self._value = # <complex code that produces value>
return self._value
In this way, self._value is computed only once and all the other times the precomputed value is returned. So far so good.
Now, let's suppose I want to subclass A with class B. In our case class B will have its own method of computing self._value but it sometimes will need A's value, like in this example:
class B(A):
def __init__(self, a, b):
super().__init__(a, b)
@property
def value(self):
if self._value is not None:
self._value = # <complex code that produces B's version of value>
return self._value
def get_old_value(self):
return super().value # here comes the trouble
Now, clearly the trouble is that if get_old_value() is called before value() it will cache A's value forever. If value() is called before get_old_value() in the same way, get_old_value() will actually always return value().
Of course, one could simply use A's <complex code that produces value>, in the implementation of get_old_value() but that would duplicate code (which would pretty much make subclassing useless) or even wrap <complex code that produces value> inside another method in A and call that method in get_old_value() but this would not use caching at all.
Another way could be the following:
def get_old_value(self):
result = super().value
self._c = None
return result
but that would anyway remove caching for A's version of value and does not look clean at all. Is there any better way to accomplish this?
One thing I want to add is that in my code A and B make really sense as superclass and subclass, otherwise I would consider composition.