用描述符实现缓存功能和property实现原理

class Lazyproperty:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):
        print('这是我们自己定制的静态属性,r1.area实际是要执行r1.area()')
        if instance is None:
            return self  # 如果没有传进实例,那就返回area   -- > area=Lazyproperty(area)
        else:
            print('--->')
            value = self.func(instance)  # 是描述符帮我们实现了自动传值
            setattr(instance, self.func.__name__, value)  # 计算一次就缓存到实例的属性字典中
            return value


class Room:
    def __init__(self, name, width, length):
        self.name = name
        self.width = width
        self.length = length

    @Lazyproperty  # area=Lazyproperty(area) 相当于'定义了一个类属性,即描述符'
    def area(self):
        return self.width * self.length


r1 = Room('alex', 1, 1)
print(r1.area)  # 先从自己的属性字典找,没有再去类的中找,然后出发了area的__get__方法
print(r1.area)  # 先从自己的属性字典找,找到了,是上次计算的结果,这样就不用每执行一次都去计算

如果给Lazyproperty加了__set__,那就会变成数据描述符,数据描述符的优先级是大于实例属性的,这样就会去调用数据描述符,缓存就失效了。

原文地址:https://www.cnblogs.com/lshedward/p/10424206.html