hasattr + __getattr__: I think this is Python bug
Jean-Michel Pichavant
jeanmichel at sequans.com
Tue Jul 20 11:52:25 EDT 2010
dmitrey wrote:
> 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.
>
Here are some solutions in my humble order of preference:
1/ ask the user to always fill the size field
2/ ask the user to never fill the size filed (you can override
__setattr__ to make sure...)
3/ override __setattr__ to set __size instead of size
JM
More information about the Python-list
mailing list