Postpone creation of attributes until needed
George Sakkis
george.sakkis at gmail.com
Mon Jun 11 11:22:58 EDT 2007
On Jun 11, 10:37 am, Frank Millman <f... at chagford.com> wrote:
> On Jun 11, 3:38 pm, George Sakkis <george.sak... at gmail.com> 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
More information about the Python-list
mailing list