你想将一个只读属性定义成一个property,并且只在访问的时候才会计算结果。 但是一旦被访问后,你希望结果值被缓存起来,不用每次都去计算。
定义一个延迟属性的一种高效方法是通过使用一个描述器类。
class Delayproperty:
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
import math
class Circle:
def __init__(self, radius):
self.radius = radius
@Delayproperty
def area(self):
print('Computing area')
return math.pi * self.radius ** 2
@Delayproperty
def perimeter(self):
print('Computing perimeter')
return 2 * math.pi * self.radius
if __name__ == "__main__":
c = Circle(8)
print(c.area)
--------------------------------------
Computing area
201.06192982974676
201.06192982974676
很多时候,构造一个延迟计算属性的主要目的是为了提升性能。 例如,你可以避免计算这些属性值,除非你真的需要它们。 这里演示的方案就是用来实现这样的效果的, 只不过它是通过以非常高效的方式使用描述器的一个精妙特性来达到这种效果的。