今天看文章看到一个很神奇的东西,那就是文章之主题——lazy property。自己也百度了好几篇文章,琢磨了一会儿才明白其中之奥秘,分享给大家。
python中的@符

def outter(func):
    def inner(*args, **kwargs):
        print('装饰a....')
        re=func(*args, **kwargs)
        return re   

    return inner
@outter
def a():
    print("被装饰了。。。")

a()

上面一段装饰器的代码,相信大家都明白其原理,通过装饰器a指向了outter的返回值,也就是其内部函数inner,然后调用a,其实调用的是被装饰后的函数。那么接下来,引入我们今天的话题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)   #三次的结果都是:50.24

上面的代码引用自飘逸的python,其不仅用到了我们上面的@符作用,更是用到了昨天讲的属性描述器。当第一次执行的时候先被lazy类初始化并赋给其实例变量func,然后再被__get__函数执行并将返回值赋给变量val,被通过python内置函数setter()将area属性加入c实例中(c.__dict__),最后返回val。这种方式可以简化我们的计算操作。
最后给大家扩展一个小知识点(见名之意我就不多嘴了):
setter(object,name,value)
getter(object,name, not_exists_value)
hasattr(object,name)
只想踏踏实实的学好一门语言,有不足的地方,大家多多留言提出来,谢谢了。


二十一
1.4k 声望867 粉丝

无论遇到多大的困难,你总是能扛过去,坚持一件事,对自己