【发布时间】:2020-05-12 17:45:00
【问题描述】:
在我的场景中,我有一个包含许多属性的类。这些属性不带任何参数,它们的计算时间很长,并且它们的结果在程序生命周期内不应该改变。
我想缓存那些属性的结果,所以繁重的计算只进行一次。我采用的方法是使用装饰器:
def cached(f):
def wrapper(*args):
# get self
class_self = args[0]
cache_attr_name = '_' + f.__name__
if hasattr(class_self, cache_attr_name):
return getattr(class_self, cache_attr_name)
else:
result = f(*args)
setattr(class_self, cache_attr_name, result)
return result
return wrapper
然后在缓存的类成员中:
class MyClass():
@property
@cached
def heavy_prop(self):
# In the actual class, the heavy calculation happens here
return 1
对于这种情况的更好/其他解决方案有什么想法吗?
【问题讨论】:
-
为什么使用装饰器而不是直接函数调用?
-
我通常会选择显式选项来检查
_heavy_prop是否为None(在这种情况下,属性将计算其值并将其存储在_heavy_prop中),否则返回它。是否也有必须使缓存失效的时候? -
以@sim 为基础是在谈论;你可以做的是定义一个类变量,它应该包含
heavy_prop的特定值,如果在调用MyClass.heavy_prop()时没有设置该值,你应该在那里设置变量。 -
@sim 我不需要使缓存失效。您的建议是在 MyClass 的构造函数中定义一个新成员
_heavy_prop=None,而不是像我一样在装饰器中动态添加它? -
@macr0controller:确实,这是我的建议。在这种情况下,您的代码的读者会更清楚正在发生的事情。当然,您要付出“代价”,您必须检查您的“protected”属性属性(例如
_heavy_prop)在每个属性中是否为None。
标签: python caching decorator python-decorators