python 惰性属性_Python语言入门6.6-类的惰性属性

本文主要向大家介绍了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.0calling 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 

c.area = 66

AttributeError: can't set attribute

之后改变c.area的值,发现报错,不能被修改。这样就修复了第一种方法中计算值可以被外部改变的bug。这种方法的缺点就是所有的get操作都必须经由属性的getter函数来处理。这比直接在实例字典中查找相应的值要慢一些。

本文由职坐标整理并发布,了解更多内容,请关注职坐标编程语言Python频道!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值