例如,我有一个类可以缓存一些值以避免多次计算它们
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
这样,self._value
仅计算一次,所有其他时间都返回预先计算的值。到目前为止一切顺利。
现在,假设我想要子类 A
与类B
。在我们的案例中类 B
会有自己的计算方法self._value
但有时需要A
的value
,就像这个例子一样:
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
现在,显然问题是如果 get_old_value()
在 value()
之前调用它将缓存A
的value
永远。如果value()
在 get_old_value()
之前调用同理,get_old_value()
实际上总是返回 value()
.
当然,可以简单地使用 A
的<complex code that produces value>
,在执行get_old_value()
但这会重复代码(这几乎会使子类化变得毫无用处)甚至包装 <complex code that produces value>
在 A
中的另一个方法中并在 get_old_value()
中调用该方法但这根本不会使用缓存。
另一种方法可能如下:
def get_old_value(self):
result = super().value
self._c = None
return result
但这无论如何都会删除 A
的缓存value
的版本而且看起来一点也不干净。有没有更好的方法来实现这一点?
我想添加的一件事是在我的代码中 A
和B
作为父类(super class)和子类确实有意义,否则我会考虑组合。
最佳答案
您需要做的是使用名称修改——这将允许每个类/子类维护变量的私有(private)版本,这样它们就不会互相破坏:
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 = 7
return self.__value
class B(A):
def __init__(self, a, b):
super().__init__(a, b)
self.__value = None
@property
def value(self):
if self.__value is None:
self.__value = 17
return self.__value
def get_old_value(self):
return super().value # no more trouble here
使用中:
>>> b = B(1, 2)
>>> print(b.value)
17
>>> print(b.get_old_value())
7
请注意,您现在还需要在 B
的 __init__
中设置 __value
。
另请参阅this answer有关名称修改的更多花絮。
关于python-3.x - 在父类(super class)中缓存属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42914246/