hasattr + __getattr__: I think this is Python bug

dmitrey dmitrey.kroshko at scipy.org
Tue Jul 20 11:32:39 EDT 2010


On 20 июл, 15:00, Jean-Michel Pichavant <jeanmic... at sequans.com>
wrote:
> 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

This doesn't stack with the following issue: sometimes user can write
in code "myObject.size = (some integer value)" and then it will be
involved in future calculations as ordinary fixed value; if user
doesn't supply it, but myObject.size is involved in calculations, then
the oofun is created to behave like similar numpy.array attribute.



More information about the Python-list mailing list