后续行动:超类中的属性缓存 [英] Followup: attribute caching in superclasses
问题描述
这是此问题的后续操作.我有一个为它的子类缓存属性的类:
This is a followup to this question. I have a class which caches an attribute for its subclasses:
class A(object):
def __init__(self):
self._value = None
@property
def value(self):
if self._value is None:
self._value = self.complex_computation()
return self._value
def complex_computation(self):
raise NotImplemented
现在,让我们假设我有许多 A
的子类,每个子类仅覆盖 complex_computation()
,因此将缓存机制委托给父类.现在让我们假设其中一个类是 B
,而 B
本身具有一个子类,即 C
:
Now, let's suppose I have many subclasses of A
, each one overriding only complex_computation()
, hence delegating the caching mechanism to the parent class. Now let's suppose one of this classes is B
and B
has a subclass itself, C
:
class B(A):
def complex_computation(self):
return # B's complex computation happens here
class C(B):
def complex_computation(self):
return # C's complex computation happens here
但是,我们假设 C
也想返回 B
的 value
,但仍使用类 A
. C
可以添加以下方法:
However, let's assume that C
also wants to return B
's value
still making use of the caching mechanism defined in class A
. C
could add the following method:
def parent_complex_computation(self):
return super().value # this does not work
如上一个问题中所述,这将不起作用.实际上,如果一个人首先访问 C
的 value
,那么 parent_complex_computation()
将始终返回该版本.第一次使用 parent_complex_computation()
并缓存 B
的值时,也会发生同样的问题.
As described in the previous question, this would not work. In fact, if one accesses C
's value
first, then parent_complex_computation()
would always return that version. Same problem happens when parent_complex_computation()
is used first, caching B
's value.
如上一个问题所回答,名称修改(即使用 self .__ value
代替 A
中的 self._value
)可以解决问题,但在这种情况下, A
的每个子类都应将缓存机制重新定义为其自身的属性和重新定义的属性.有没有更好的方法可以将缓存机制仅保留在类 A
中而不重复代码,同时允许子类覆盖重写的缓存方法 complex_computation
并调用父级缓存的 value
,因此同时缓存两个值?
As answered in the previous question, name mangling (i.e. using self.__value
instead of self._value
in A
) could solve the problem, but in that case every subclass of A
should redefine both the caching mechanism as its own property and the mangled attribute. Is there a better way to keep the caching mechanism only in class A
and not duplicating code, while allowing a subclass to both override the cached method complex_computation
AND call the parent's cached value
, hence caching both values?
推荐答案
您有两种选择:
-
重新设计
__ init __
来找出正确的名称拼写版本,以便始终适用于该类所在的类
redesign
__init__
to figure out the correct name-mangled version of the name so it is always appropriate for the class it is in
将缓存行为移至 complex_computation()
方法
我将展示第二种方法:
def complex_computation(self, _cache=[]):
if not _cache:
# calculate
# ...
# calculated_value = ...
#
# and save
_cache.append(calculated_value)
return _cache[0]
然后,当您想查看直系父母的价值时:
And then when you want to see your immediate parent's value:
def get_parent_calculation(self):
return super().complex_computation()
这篇关于后续行动:超类中的属性缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!