python-3.x - 在父类(super class)中缓存属性

标签 python-3.x inheritance caching properties

例如,我有一个类可以缓存一些值以避免多次计算它们

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但有时需要Avalue ,就像这个例子一样:

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() 之前调用它将缓存Avalue永远。如果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 的版本而且看起来一点也不干净。有没有更好的方法来实现这一点?

我想添加的一件事是在我的代码中 AB作为父类(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/

相关文章:

python-3.x - 如何在 Python 中将制表符分隔的文本文件转换为 csv 文件

css - ReactJS 嵌套内联样式

apache - 为什么 Internet Explorer 缓存过期的 SSL 证书(我可以对此做些什么)?

python - 如何计算列表中元素的数量并创建新列?

python-3.x - smtplib, 'tuple' 对象没有属性 'encode'

python - 从 SOAP 响应中解析多个值

java - 继承:从子类访问基类字段

c++ - 我可以更改默认继承的访问器吗?

jquery - 使用 jQuery 清除浏览器缓存

ruby-on-rails - Rails jbuilder 缓存+查询