From: dmitrey on
On 20 июл, 15:00, Jean-Michel Pichavant <jeanmic...(a)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.
From: dmitrey on
> e.g. one that just looks in the object's dictionary so as to avoid returning true for properties or other such fancy attributes.

So can anyone explain me how to look into object's dict? As I have
wrote, "something in dir(...)" requires O(numOfFields) while I would
like to use o(log(n))

>How about using a property instead of the __getattr__() hook? A property is a computed attribute that (among other things) plays much nicer with hasattr.

Could anyone provide an example of it to be implemented, taking into
account that a user can manually set "myObject.size" to an integer
value?
From: Neil Cerutti on
On 2010-07-20, dmitrey <dmitrey.kroshko(a)scipy.org> wrote:
> 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.

Telling them, "Don't do that," is a good solution in Python.

--
Neil Cerutti
From: dmitrey on
On 20 июл, 18:39, Neil Cerutti <ne...(a)norwich.edu> wrote:
> On 2010-07-20, dmitrey <dmitrey.kros...(a)scipy.org> wrote:
>
> > 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.
>
> Telling them, "Don't do that," is a good solution in Python.
>
> --
> Neil Cerutti

But this is already documented feature, and it works as intended, so
moving it into something like "myObject._size" will bring backward
incompatibility and break all FuncDesigner user API and style, where
no underlines are present, it will seem like a hack that it really
is.

Sometimes apriory knowing size value as fixed integer brings some code
speedup, also, if a user supplies the value, a check for computed
value wrt the provided size is performed each time.
From: Jean-Michel Pichavant on
dmitrey wrote:
> On 20 июл, 15:00, Jean-Michel Pichavant <jeanmic...(a)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