How to instantiate in a lazy way?

Nick Craig-Wood nick at craig-wood.com
Tue Dec 2 11:30:46 CET 2008


Slaunger <Slaunger at gmail.com> wrote:
>  On 1 Dec., 16:30, Nick Craig-Wood <n... at craig-wood.com> wrote:
> >
> > I wouldn't use __getattr__ unless you've got lots of attributes to
> > overload. ?__getattr__ is a recipe for getting yourself into trouble
> > in my experience ;-)
> >
> > Just do it like this...
> >
> > class PayloadOnDemand(object):
> > ? ? ? def __init__(self, a_file, a_file_position):
> > ? ? ? ? ? self._data = None
> > ? ? ? ? ? self.f = a_file
> > ? ? ? ? ? self.file_position = a_file_position
> >
> > ? ? ? @property
> > ? ? ? def data(self):
> > ? ? ? ? ? if self._data is None:
> > ? ? ? ? ? ? ? self._data = self.really_read_the_data()
> > ? ? ? ? ? return self._data
> >
> > then you'll have a .data attribute which when you read it for the
> > first time it will populate itself.
> >
> > If None is a valid value for data then make a sentinel, eg
> >
> > class PayloadOnDemand(object):
> > ? ? ? sentinel = object()
> >
> > ? ? ? def __init__(self, a_file, a_file_position):
> > ? ? ? ? ? self._data = self.sentinel
> > ? ? ? ? ? self.f = a_file
> > ? ? ? ? ? self.file_position = a_file_position
> >
> > ? ? ? @property
> > ? ? ? def data(self):
> > ? ? ? ? ? if self._data is self.sentinel:
> > ? ? ? ? ? ? ? self._data = self.really_read_the_data()
> > ? ? ? ? ? return self._data
> >
> >
> > - Vis tekst i anf?rselstegn -
> 
>  OK, I get it. In my case I have four attributes to create when one of
>  them is accessed, I do not know if that is a lot of attributes;-) One
>  thing I like about the __getattr__ is that it is only called that one
>  single time where an attempt to read a data attribute fails because
>  the attribute name is not defined in the __dict__ of the object.

For 4 attributes I'd probably go with the __getattr__.

Or you could easily write your own decorator to cache the result...

Eg http://code.activestate.com/recipes/363602/

>  With the property methology you do the value check on each get, which
>  does not look as "clean". The property methology is also a little less
>  arcane I guess for less experienced Python programmers to understand
>  when re-reading the code.

Less magic is how I would put it.  Magic is fun to write, but a pain
to come back to.  Over the years I find I try to avoid magic more and
more in python.

>  What kind of trouble are you referring to in __getattr__? Is it
>  recursive calls to the method on accessing object attributes in that
>  method itself or other complications?

Every time I write a __getattr__ I get tripped up by infinite
recursion!  It is probably just me ;-)

>  On a related issue, thank you for showing me how to use @property as a
>  decorator - I was not aware of that possibility, just gotta understand
>  how to decorate a setter and delete method as well, but I should be
>  able to look that up by myself...

I'm sure you will!

http://www.python.org/doc/2.5.2/lib/built-in-funcs.html

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list