@cached_property 缓存装饰器

本文介绍了如何创建一个基于类的缓存装饰器,该装饰器用于提高代码效率,减少重复计算。装饰器实现了`__get__`和`__set__`方法,确保在获取属性时优先从描述器中查找。在Django源码中也有类似的实现,当尝试访问属性时,如果未找到,则将其计算并存储在实例字典中,以便后续访问直接获取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以class为基础的缓存装饰器(自定义的)

class cached_property(property):

    """A decorator that converts a function into a lazy property.  The
    function wrapped is called the first time to retrieve the result
    and then that calculated result is used the next time you access
    
    The class has to have a `__dict__` in order for this property to
    work.
    """

    # implementation detail: A subclass of python's builtin property
    # decorator, we override __get__ to check for a cached value. If one
    # choses to invoke __get__ by hand the property will still work as
    # expected because the lookup logic is replicated in __get__ for
    # manual invocation.

    def __init__(self, func, name=None, doc=None):
        self.__name__ = name or func.__name__
        self.__module__ = func.__module__
        self.__doc__ = doc or func.__doc__
        self.func = func

    def __set__(self, obj, value):
        obj.__dict__[self.__name__] = value

    def __get__(self, obj, type=None):
        if obj is None:
            return self
        value = obj.__dict__.get(self.__name__, _missing)
        if value is _missing:
            value = self.func(obj)
            obj.__dict__[self.__name__] = value
        return value

使用该装饰器

from django.utils.functional import cached_property

class Foo:
    @cached_property
    def foo(self):
        print('========执行foo==========')
        a=12
        return a

f=Foo()

print(f.foo)

print(f.foo)

print(f.foo)

***************************************************************************
执行结果:

========执行foo==========
12
12
12

cached_property 是 property 的subclass, 复写了 __get____set__ 方法.

cached_property 是一个描述器(资料描述器),获取属性的时候优先从描述器获取,即(__get__).

所以执行流程就是:
f.foo -> __get__ -> 从实例字典(f.__dict__)获取 -> 如果没有则保存到字典并调用实际方法返回


Django 源码 

class cached_property(object):
    """
    Decorator that converts a method with a single self argument into a
    property cached on the instance.

    Optional ``name`` argument allows you to make cached properties of other
    methods. (e.g.  url = cached_property(get_absolute_url, name='url') )
    """
    def __init__(self, func, name=None):
        self.func = func
        self.__doc__ = getattr(func, '__doc__')
        self.name = name or func.__name__

    def __get__(self, instance, cls=None):
        if instance is None:
            return self
        res = instance.__dict__[self.name] = self.func(instance)
        return res

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值