On Jun 11, 10:37 am, Frank Millman <[EMAIL PROTECTED]> wrote: > On Jun 11, 3:38 pm, George Sakkis <[EMAIL PROTECTED]> wrote: > >The boilerplate code can be minimal too with an appropriate > > decorator, something like: > > > class A(object): > > > def __init__(self,x,y): > > self.x = x > > self.y = y > > > @cachedproperty > > def z(self): > > return self.x * self.y > > > where cachedproperty is > > > def cachedproperty(func): > > name = '__' + func.__name__ > > def wrapper(self): > > try: return getattr(self, name) > > except AttributeError: # raised only the first time > > value = func(self) > > setattr(self, name, value) > > return value > > return property(wrapper) > > This is very neat, George. I will have to read it a few more times > before I understand it properly - I still have not fully grasped > decorators, as I have not yet had a need for them.
You never *need* decorators, in the sense it's just syntax sugar for things you might do without them, but they're handy once you get your head around them. > Actually I did spend a bit of time trying to understand it before > posting, and I have a question. > > It seems that this is now a 'read-only' attribute, whose value is > computed by the function the first time, and after that cannot be > changed. It would probably suffice for my needs, but how easy would it > be to convert it to read/write? It's straightforward, just define a setter wrapper and pass it in the property along with the getter: def cachedproperty(func): name = '__' + func.__name__ def getter(self): try: return getattr(self, name) except AttributeError: # raised only the first time value = func(self) setattr(self, name, value) return value def setter(self, value): setattr(self, name, value) return property(getter,setter) HTH, George -- http://mail.python.org/mailman/listinfo/python-list