【发布时间】:2016-09-27 14:07:12
【问题描述】:
我有两个类,其中一个的设置成本很高,但可重用,另一个在我的应用程序中有很多实例,但可以重用昂贵类的实例。这更容易通过例子来解释:
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'
我发现了几种用于记忆装饰器的模式,但没有找到用于静态属性的模式。我错过了什么吗?或者我应该使用其他模式吗?
编辑:
我的问题过于简单化了:我应该在配置文件中包含 SomeExpensiveToSetUpClass 类实现的名称,所以直到第一次实例化 OftenUsedClass 时我才知道它的名称。
【问题讨论】:
-
我不确定我是否正确地遵循了你,因为你的例子相当复杂,但你不能将
SomeExpensiveToSetUpClass()转换为单例(因为该类只有一个实例),然后调度所有需要在“OftenUsedClass”中调用该单例吗? -
@Rogalski - 谢谢!我添加了一个说明,说明为什么单例是不可能的。对不起,我第一次不够清楚。
-
也许这个describing a lazily calculated class attribute 会有用。你可以在这里使用
@class_reify def expensive_property(): return SomeExpensiveToSetUpClass() -
对不起,那是
def expensive_property(cls)
标签: python python-3.x memoization