##缓存之后允许更改
class 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

import math

##缓存之后不允许更改
def lazyproperty2(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

class Circle:
  def __init__(self,radius):
    self.radius=radius

  @lazyproperty
  def area(self):
    print('Computing area')
    return math.pi*self.radius**2

  @lazyproperty2
  def perimeter(self):
    print('Computing perimeter')
    return 2*math.pi*self.radius

c=Circle(4.0)
print(c.area)
print(c.perimeter)

c.area=20
print(c.area)

##error
c.perimeter=30
print(c.perimeter)
