在我的情况下,我有一个带有许多属性的类。这些属性不带任何参数,它们占用大量的计算时间,并且它们的结果在程序生命周期中不应更改。
我想缓存那些属性的结果,因此繁重的计算仅执行一次。我采用的方法是装饰器:
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
是否有针对这种情况的更好/其他解决方案的想法?
对于Python 3.8,使用内置的cached_property
:https://docs.python.org/dev/library/functools.html#functools.cached_property
对于较旧的版本,请使用库https://github.com/pydanny/cached-property
或仅使用此代码:
class cached_property(object):
"""
A property that is only computed once per instance and then replaces itself
with an ordinary attribute. Deleting the attribute resets the property.
Based on https://github.com/pydanny/cached-property/blob/master/cached_property.py
"""
def __init__(self, func):
self.__doc__ = func.__doc__
self.func = func
def cached_property_wrapper(self, obj, _cls):
if obj is None:
return self
value = obj.__dict__[self.func.__name__] = self.func(obj)
return value
__get__ = cached_property_wrapper