Postpone creation of attributes until needed

Frank Millman frank at chagford.com
Mon Jun 11 08:27:35 EDT 2007


On Jun 11, 1:56 pm, Steven D'Aprano
<s... at REMOVE.THIS.cybersource.com.au> wrote:
>
> Unless you have thousands and thousands of instances, __slots__ is almost
> certainly not the answer. __slots__ is an optimization to minimize the
> size of each instance. The fact that it prevents the creation of new
> attributes is a side-effect.
>

Understood - I am getting there slowly.

I now have the following -

>>> class A(object):
...    def __init__(self,x,y):
...        self.x = x
...        self.y = y
...    def __getattr__(self,name):
...        print 'getattr',name
...        self.compute()
...        return self.__dict__[name]
...    def compute(self):  # compute all missing attributes
...        self.__dict__['z'] = self.x * self.y
           [there could be many of these]

>>> a = A(3,4)
>>> a.x
3
>>> a.y
4
>>> a.z
getattr z
12
>>> a.z
12
>>> a.q
KeyError: 'q'

The only problem with this is that it raises KeyError instead of the
expected AttributeError.

>
> You haven't told us what the 'compute' method is.
>
> Or if you have, I missed it.
>

Sorry - I made it more explicit above. It is the method that sets up
all the missing attributes. No matter which attribute is referenced
first, 'compute' sets up all of them, so they are all available for
any future reference.

To be honest, it feels neater than setting up a property for each
attribute.

I would prefer it if there was a way of raising AttributeError instead
of KeyError. I suppose I could do it manually -

    try:
        return self.__dict__[name]
    except KeyError:
        raise AttributeError,name

Frank




More information about the Python-list mailing list