今天看文章看到一个很神奇的东西,那就是文章之主题——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)
只想踏踏实实的学好一门语言,有不足的地方,大家多多留言提出来,谢谢了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。