1

我有一个类,我需要访问只能按子类计算的计算值。这种计算并不便宜,而且由于子类有很多实例,我想每个子类只计算一次这个值。

我可以想到两个我不太喜欢的解决方案:

父类将有一个@classmethod start()将计算值的。这迫使我确定每个类的第一个实例化的精确位置,所以我已经排除了这个选项。

或者,这段代码:

class A(object):
    @classmethod
    def _set_cls_attribute(cls):
        if hasattr(cls, 'big_attr'):
            return
        cls.big_attr = heavy_func(cls.VAL)

    def __init__(self):
        self._set_cls_attribute()

class B(A):
        VAL = 'b'

class C(A):
        VAL = 'c'


for _ in range(large_number):
        b = B()
        c = C()

我不喜欢使用hasattr...有什么更好的吗?

4

2 回答 2

1

元类是解决此问题的便捷方法

class A_meta(type):
    def __init__(cls, *args):
        type.__init__(cls, *args)
        if hasattr(cls, 'VAL'):
            cls.big_attr = heavy_func(cls.VAL)

class A(object):
    __metaclass__ = A_meta

class B(A):
        VAL = 'b'

class C(A):
        VAL = 'c'

与您的路线相同的另一种方式。这样做的好处是可以推迟对 heavy_func 的调用,直到第一次访问该属性。

class A(object):
    def __getattr__(self, attr):
        if attr == 'big_attr':
            self.__class__.big_attr = heavy_func(self.VAL)
        return object.__getattribute__(self, attr)
于 2013-03-07T14:46:08.967 回答
1

没有元类或 hasattr :

class A(object):
   @classmethod
   def attribute(cls):
       v = heavy_func(cls.VAL)
       cls.attribute = lambda k : v
       return v
于 2013-03-07T14:49:21.323 回答