From: Robert Kern on
On 7/20/10 6:59 AM, dmitrey wrote:
> On Jul 20, 1:37 pm, Chris Rebert<c...(a)rebertia.com> wrote:

>> Least ugly suggestion: Just don't use hasattr(); use your `x in
>> dir(y)` trick instead.
>
> something in dir() consumes O(n) operations for lookup, while hasattr
> or getattr() require O(log(n)). It matters for me, because it's inside
> deeply nested mathematical computations FuncDesigner is made for.

I'm not sure where you are getting log(n) from, but regardless, if you have so
many attributes that the O() matters more than the constant, you have more
problems than this.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

From: Robert Kern on
On 7/20/10 11:39 AM, dmitrey wrote:
>> 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))

('size' in obj.__dict__) is O(1) with a pretty low constant.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco

From: Ian Kelly on
On Tue, Jul 20, 2010 at 9:39 AM, dmitrey <dmitrey.kroshko(a)scipy.org> wrote:
>>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?

The following will work in Python 2.6+:

class MyClass(object):

@property
def size(self):
if not hasattr(self, '_size'):
self._size = self._compute_size()
return self._size

@size.setter
def size(self, value):
self._size = value


To support earlier versions of Python, you would write it like so:

class MyClass(object):

def _get_size(self):
if not hasattr(self, '_size'):
self._size = self._compute_size()
return self._size

def _set_size(self, value):
self._size = value

size = property(_get_size, _set_size)
From: Bruno Desthuilliers on
dmitrey a écrit :
(snip)

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

IOW, you want a default value for the size if it has not been specified
by the user, so you can safely use this attribute in computations. The
more straightforward solution is to define this attribute (with the
default value) in the initialiser, ie:


class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
self.size = Whatever()


If you don't want to create as many Whatever instances as MyClass
instances, you can create a single Whatever instance before defining
your class:

DEFAULT_WHATEVER = Whathever()

class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
self.size = DEFAULT_WHATEVER


HTH
From: Bruno Desthuilliers on
Duncan Booth a �crit :
> Bruno Desthuilliers <bruno.42.desthuilliers(a)websiteburo.invalid> wrote:
>
>> If you don't want to create as many Whatever instances as MyClass
>> instances, you can create a single Whatever instance before defining
>> your class:
>>
>> DEFAULT_WHATEVER = Whathever()
>>
>> class MyClass(object):
>> def __init__(self, x, y):
>> self.x = x
>> self.y = y
>> self.size = DEFAULT_WHATEVER
>>
>>
>
> Or you could create the default as a class attribute

from the OP:
"""
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 this solution won't obviously work in this case !-)

Also and FWIW, I wouldn't advocate this solution if the "default" class
attribute is of a mutable type.