Postpone creation of attributes until needed

Frank Millman frank at chagford.com
Mon Jun 11 05:24:51 EDT 2007


Hi all

I have a small problem. I have come up with a solution, but I don't
know if it is a) safe, and b) optimal.

I have a class with a number of attributes, but for various reasons I
cannot assign values to all the attributes at __init__ time, as the
values depend on attributes of other linked classes which may not have
been created yet. I can be sure that by the time any values are
requested, all the other classes have been created, so it is then
possible to compute the missing values.

At first I initialised the values to None, and then when I needed a
value I would check if it was None, and if so, call a method which
would compute all the missing values. However, there are a number of
attributes, so it got tedious. I was looking for one trigger point
that would work in any situation. This is what I came up with.

>>> class A(object):
...    __slots__ = ('x','y','z')
...    def __init__(self,x,y):
...        self.x = x
...        self.y = y
...    def __getattr__(self,name):
...        print 'getattr',name
...        if name not in self.__class__.__slots__:
...            raise AttributeError,name
...        self.z = self.x * self.y
...        return getattr(self,name)

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

In other words, I do not declare the unknown attributes at all. This
causes __getattr__ to be called when any of their values are
requested, and __getattr__ calls the method that sets up the
attributes and computes the values.

I use __slots__ to catch any invalid attributes, otherwise I would get
a 'maximum recursion depth exceeded' error.

Is this ok, or is there a better way?

Thanks

Frank Millman




More information about the Python-list mailing list