在Python

时间:2016-05-29 19:14:25

标签: python python-3.x memoization

我有两个类,其中一个设置成本高,但可重用,另一个在我的应用程序中有很多实例,但可以重用昂贵类的实例。通过示例更容易解释:

class SomeExpensiveToSetUpClass(object):
    def __init__(self):
        print("Expensive to set up class initialized")
        self.whatever = "Hello"

    def do_the_thing(self):
        print(self.whatever)

class OftenUsedClass(object):

    @staticmethod
    @property
    def expensive_property():
        try:
            return OftenUsedClass._expensive_property
        except AttributeError:
            OftenUsedClass._expensive_property = SomeExpensiveToSetUpClass()
            return OftenUsedClass._expensive_property

    # I know I could hide the static property in an instance property:
    @property
    def expensive_property2(self):
        try:
            return OftenUsedClass._expensive_property
        except AttributeError:
            OftenUsedClass._expensive_property = SomeExpensiveToSetUpClass()
            return OftenUsedClass._expensive_property
    #
    # And then:
    #
    # ouc = OftenUsedClass()
    # ouc.expensive_property2.do_the_thing()
    # ouc.expensive_property2.do_the_thing()
    # ouc.expensive_property2.do_the_thing()
    #
    # but that feels misleading

if __name__ == '__main__':
    OftenUsedClass.expensive_property.do_the_thing()
    OftenUsedClass.expensive_property.do_the_thing()
    OftenUsedClass.expensive_property.do_the_thing()

尽可能地看,我希望我会使用@staticmethod@property在第一次使用该属性时基本上记住该属性,但没有骰子 - 我得到一个实例取而代之的是property

Traceback (most recent call last):
  File "memo.py", line 39, in <module>
    OftenUsedClass.expensive_property.do_the_thing()
AttributeError: 'property' object has no attribute 'do_the_thing'

我发现了几种用于memoization装饰器的模式,但是没有一种用于静态属性。我错过了什么吗?或者我应该使用另一种模式吗?

修改

我过度简化了我的问题:我应该在配置文件中提供SomeExpensiveToSetUpClass类实现的名称,所以直到第一次OftenUsedClass我都不知道它的名字实例化。

1 个答案:

答案 0 :(得分:1)

建议possible duplicate已结束。 classmethod装饰器的工作原理如下:

class classproperty(object):
    def __init__(self, getter):
        self.getter = getter
    def __get__(self, instance, owner):
        return self.getter(owner)

但是没有必要在课外定义任何东西,所以:

class OftenUsedClass(object):

    @classproperty
    def expensive_property3(cls):
        try:
            return cls._expensive_property
        except AttributeError:
            cls._expensive_property = SomeExpensiveToSetUpClass()
            return cls._expensive_property

工作正常。