[通过装饰器在python中缓存属性的结果

问题描述 投票:0回答:1

在我的情况下,我有一个带有许多属性的类。这些属性不带任何参数,它们占用大量的计算时间,并且它们的结果在程序生命周期中不应更改。

我想缓存那些属性的结果,因此繁重的计算仅执行一次。我采用的方法是装饰器:

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 caching decorator python-decorators
1个回答
0
投票

对于Python 3.8,使用内置的cached_propertyhttps://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
© www.soinside.com 2019 - 2024. All rights reserved.