后续行动:超类中的属性缓存 [英] Followup: attribute caching in superclasses

查看:53
本文介绍了后续行动:超类中的属性缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是此问题的后续操作.我有一个为它的子类缓存属性的类:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆