hasattr + __getattr__: I think this is Python bug

Jean-Michel Pichavant jeanmichel at sequans.com
Tue Jul 20 08:00:39 EDT 2010


dmitrey wrote:
> hi all,
> I have a class (FuncDesigner oofun) that has no attribute "size", but
> it is overloaded in __getattr__, so if someone invokes
> "myObject.size", it is generated (as another oofun) and connected to
> myObject as attribute.
>
> So, when I invoke in other code part "hasattr(myObject, 'size')",
> instead o returning True/False it goes to __getattr__ and starts
> constructor for another one oofun, that wasn't intended behaviour.
> Thus "hasattr(myObject, 'size')" always returns True. It prevents me
> of some bonuses and new features to be done in FuncDesigner.
>
>   
>>>> 'size' in dir(b)
>>>>         
> False
>   
>>>> hasattr(b,'size')
>>>>         
> True
>   
>>>> 'size' in dir(b)
>>>>         
> True
>
> Could you fix it?
>   

Quite simple, when calling b.size, return the computed value but do not 
set it as attribute, the value will be computed on each b.size call, and 
hasattr w. If you don't want to compute it each time, cause there no 
reason for it to change, use a private dummy attribute to record the 
value instead of size (__size for instance) and return the value of 
__size when getting the value of size.


class Foo(object):
    def __init__(self):
        self.__size = None

    def __getattr__(self, name):
        if name == "size":
            if self.__size is None:
                self.__size = 5 # compute the value
            return self.__size
        raise AttributeError(name)

b = Foo()
print 'size' in dir(b)
print hasattr(b, 'size')
print 'size' in dir(b)

False
True
False

JM



More information about the Python-list mailing list