Postpone creation of attributes until needed

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Tue Jun 12 01:46:07 CEST 2007


On Mon, 11 Jun 2007 05:27:35 -0700, Frank Millman wrote:


> 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.


Yes, because you never assign __dict__['q'].


>> 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.


If you're going to do that, why not call compute() from your __init__ code
so that initializing an instance sets up all the attributes? That way you
can remove all the __getattr__ code. Sometimes avoiding the problem is
better than solving the problem.



-- 
Steven.




More information about the Python-list mailing list