摘要:本文主要向大家介绍了Python语言入门的类的惰性属性,通过具体的内容向大家展现,希望对大家学习Python语言入门有所帮助。
本文主要向大家介绍了Python语言入门的类的惰性属性,通过具体的内容向大家展现,希望对大家学习Python语言入门有所帮助。
我们想将一个只读属性定义为property属性方法,只有在访问它时才参与计算。同时,一旦访问了该属性,希望把计算出来的值缓存起来,不要每次访问它时都要重新计算。这样就能很大程度上提升程序的性能。定义一个惰性属性最简单的方法就是利用描述符来完成。
#define a lazypropertyclass Lazyproperty: def __init__(self,func): self.func = func def __get__(self,instance,cls): if instance is None: return self else: value = self.func(instance) setattr(instance,self.func.__name__,value) return value #Exampleimport mathclass Circle: def __init__(self,radius): self.radius = radius @Lazyproperty def area(self): print('Computing area') return math.pi*self.radius*2 @Lazyproperty def perimeter(self): print('Computing perimeter') return 2*math.pi*self.radius c = Circle(4.0) print(c.radius) print('calling c.area the first time:') print(c.area) print('calling c.area the second time:') print(c.area) 打印输出:4.0 calling c.area the first time: Computing area25.132741228718345 calling c.area the second time:25.132741228718345
从示例中可以很清楚的看出,第一次调用c.area时计算过程被执行,第二次调用它的时候,计算过程没有执行,是因为计算一次之后,它的值就被储存起来了,第二次直接拿出来用,从而加快了程序的运行。
前面提到描述符的时候讲过,当吧描述符放到类的定义体中的时候,访问它的属性会出发get(),set(),delete()方法。但是,如果一个描述符只定义了get()方法,则它的绑定关系比一般情况要弱化的多。特别是,只有当被访问的属性不在底层的实例字典中时,_get_()方法会得到调用。
但是,这种技术有一个潜在是bug,一旦使用了这种方法,计算的值就会变成可变的了。
c.area = 66
print(c.area)
打印输出:66
如果考虑到可变性,可以使用一种方法去修复这个bug,但是同时执行效率也会大大的降低。
def lazyproperty(func): name = '_lazy_' + func.__name__ @property def lazy(self): if hasattr(self,name): return getattr(self,name) else: value = func(self) setattr(self,name,value) return value return lazy #Exampleimport mathclass Circle: def __init__(self,radius): self.radius = radius @lazyproperty def area(self): print('Computing area') return math.pi*self.radius*2 @lazyproperty def perimeter(self): print('Computing perimeter') return 2*math.pi*self.radius c = Circle(4.0) print(c.radius) print('calling c.area the first time:') print(c.area) print('calling c.area the second time:') print(c.area)
打印输出:4.0
calling c.area the first time: Computing area25.132741228718345 calling c.area the second time:25.132741228718345
从该实例中可以发现,达到了同样的效果。
c.area = 66 print(c.area) Traceback (most recent call last): File "D:/home/WX/test_lazyproperty.py", line 32, in <module> c.area = 66 AttributeError: can't set attribute
之后改变c.area的值,发现报错,不能被修改。这样就修复了第一种方法中计算值可以被外部改变的bug。这种方法的缺点就是所有的get操作都必须经由属性的getter函数来处理。这比直接在实例字典中查找相应的值要慢一些。
本文由职坐标整理并发布,了解更多内容,请关注职坐标编程语言Python频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号