Postpone creation of attributes until needed

Phil Thompson phil at riverbankcomputing.co.uk
Mon Jun 11 05:47:21 EDT 2007


On Monday 11 June 2007 10:24 am, Frank Millman wrote:
> 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?

Properties...

    @property
    def z(self):
        return self.x * self.y

Phil



More information about the Python-list mailing list