python 中的lazy property

最近在看blinker模块源码。blinker模块是一个消息传递模块,flask里面用到的信号机制就是源自于blinker。

 

有很多函数打上了@lazy_property,不解。查看源码:

class lazy_property(object):
    """A @property that is only evaluated once."""

    def __init__(self, deferred):
        self._deferred = deferred # 延期的,就是func
        self.__doc__ = deferred.__doc__

    def __get__(self, obj, cls):
        if obj is None:
            return self
        value = self._deferred(obj)
        setattr(obj, self._deferred.__name__, value)
        return value

发现这是一个类装饰器,通过搜索,发现这个装饰器的作用和@property类似,不同的是,@property每次调用的时候都会对属性进行重复运算,造成了额外开销,但是@lazy_property只在第一次调用的时候进行计算,随即调用setattr(obj,name,val)把这个值保存到自己的属性里。

另外一层含义就是这个属性不是随着对象的创建而创建,而是在调用的时候才创建,所以叫做lazy property。

这是网上的一个例子:

class lazy(object):
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, cls):
        val = self.func(instance)  # 其相当于执行的area(c),c为下面的Circle对象
        setattr(instance, self.func.__name__, val)
        return val


class Circle(object):
    def __init__(self, radius):
        self.radius = radius

    @lazy
    def area(self):
        print('evalute')
        return 3.14 * self.radius ** 2


c = Circle(4)
print(c.area)
print(c.area)
print(c.area)  # 三j次的结果都是:50.24

只有第一次打印evalute

之后只打印50.24

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值