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