trap setting attribute when the attribute is dict

2007-09-03 Thread yosuke
Hello all,

I have a question which might be simple or need some work around.

I want to do something like this.  My class/instance has a dict as a
property.  I want the instance to catch the change in the dict (change
in some values, addition/deletion of key/value etc) to be recognized by
the class instance.  

How can I do this?  Any suggestions are very well appreciated.



Here is an example of what I want my class to behave:

class test(object):
def __init__(self):
self._d = {}
self._changed = False
def getd(self):
print 'called getd'
return self._d
# dont know what to do next
def setd(self,val):
print 'called setd', key, val
self._d[key] = val
self._changed = True
d = property(getd,setd,None,None)

def getc(self):
return self._changed
changed = property(getc,None,None,None)

if __name__ == '__main__':
obj = test()
print 'obj.changed = ', obj.changed
print

# I want obj to know that its propety d being changed here
print "t.d['a'] = 1"
obj.d['a'] = 1
print

# I want the "changed" property to be True
print 'obj.changed = ', obj.changed









-- 
yosuke kimura
Center for Energy and Environmental Resources
The Univ. of Texas at Austin, USA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: trap setting attribute when the attribute is dict

2007-09-03 Thread yosuke
Arnaud Delobelle <[EMAIL PROTECTED]> wrote:
> On Sep 3, 7:00 pm, <[EMAIL PROTECTED]> wrote:
>>
>> I want to do something like this.  My class/instance has a dict as a
>> property.  I want the instance to catch the change in the dict (change
>> in some values, addition/deletion of key/value etc) to be recognized by
>> the class instance.  
>>
>> How can I do this?  Any suggestions are very well appreciated.
>>
>> Here is an example of what I want my class to behave:
>>
>> class test(object):
>> def __init__(self):
>> self._d = {}
>> self._changed = False
>> def getd(self):
>> print 'called getd'
>> return self._d
>> # dont know what to do next
>> def setd(self,val):
>> print 'called setd', key, val
>> self._d[key] = val

> Where does the 'key' come from?  Perhaps you need to look further into
> how properties work.

This obviously doesn't work...

>> self._changed = True
>> d = property(getd,setd,None,None)
>>
>> def getc(self):
>> return self._changed
>> changed = property(getc,None,None,None)
>>
>> if __name__ == '__main__':
>> obj = test()
>> print 'obj.changed = ', obj.changed
>> print
>>
>> # I want obj to know that its propety d being changed here
>> print "t.d['a'] = 1"
>> obj.d['a'] = 1
>> print
>>
>> # I want the "changed" property to be True
>> print 'obj.changed = ', obj.changed
>>

> You can't do that with plain dicts, and I'm not sure it is often a
> good idea.  However you could create a class that behaves like a dict
> but calls a function each time an item is set, e.g. (made up
> terminology):

>>>> class TriggerDict(object):
> ... def __init__(self, trigger, val=None):
> ... self.trigger = trigger
> ... self.dict_ = val or {}
> ... def __setitem__(self, key, val):
> ... self.trigger(self, key, val)
> ... self.dict_[key] = val
> ... def __getitem__(self, key):
> ... return self.dict_[key]
> ...
>>>> def trigger(d, k, v):
> ... print '%s => %s' % (k, v)
> ...
>>>> td = TriggerDict(trigger)
>>>> td['spanish'] = 'inquisition' # see side effect below.
> spanish => inquisition
>>>> td['spanish']
> 'inquisition'
>>>>

> Obviously your trigger function would set the _changed attribute of
> the test object instead.  And again it is probably not a good idea
> unless you know exactly what you are doing.  If it was me, I'd try to
> rethink my design instead.

Thank you for suggestion, Arnaud.

Since you are discouraging this idea of trigger, may I ask an advice of
if my intention was legitimate one or not?

My intention was to have a propery 'sum' in my object, and which has sum
of all the values() of the dict (i have code to make sure that the value
of dict are all numeric).  I could just the propery being calculated
everytime the property got __getattr__.  But I thought that it was
inefficient to calculate the same number over and over when the value is
already known.  So I was thiking of calculating the number only when the
dict got modified.

I also experimented with the idea of subclassing dict itself to
calculate the sum.  Is this what would be better solution?

Thank you again,



> --
> Arnaud



-- 
yosuke kimura
Center for Energy and Environmental Resources
The Univ. of Texas at Austin, USA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: trap setting attribute when the attribute is dict

2007-09-03 Thread yosuke
Arnaud Delobelle <[EMAIL PROTECTED]> wrote:
> On Sep 3, 8:47 pm, <[EMAIL PROTECTED]> wrote:

> [...]

>> My intention was to have a propery 'sum' in my object, and which has sum
>> of all the values() of the dict (i have code to make sure that the value
>> of dict are all numeric).  I could just the propery being calculated
>> everytime the property got __getattr__.  But I thought that it was
>> inefficient to calculate the same number over and over when the value is
>> already known.  So I was thiking of calculating the number only when the
>> dict got modified.
>>
>> I also experimented with the idea of subclassing dict itself to
>> calculate the sum.  Is this what would be better solution?

> Why not simply have a method to update the dictionary that also keeps
> the sum up to date? Something like that:

>>>> class MyObj(object):
> ... def __init__(self):
> ... self._d = {}
> ... self._sum = 0
> ... def set_key(self, key, val):
> ... self._sum += val - self._d.get(key, 0)
> ... self._d[key] = val
> ... def get_key(self, key):
> ... return self._d[key]
> ... def sum(self):
> ... return self._sum
> ...
>>>> a = MyObj()
>>>> a.set_key(1, 2)
>>>> a.sum()
> 2
>>>> a.set_key('a', 10)
>>>> a.set_key(1, 5)
>>>> a.sum()
> 15
>>>>

> Of course this is only worth it if you need to use the sum often
> enough.
> If you update the dictionary a lot but only need the sum from time to
> time, then it might not be worth it at all.

> Of course you could subclass dict:

> class MyDict(dict):
> def __init__(self, *args, **kwargs):
> self._sum = sum(self.itervalues())
> def __setitem__(self, key, val):
> self._sum += val - self.get(key, 0)
> dict.__setitem__(self, key, val)
> def sum(self):
> return self._sum
> # overload all other methods that mutate the dict
> # to keep _sum up to date

>>>> d = MyDict()
>>>> d.sum()
> 0
>>>> d['a']=5
>>>> d.sum()
> 5
>>>> d['b']=10
>>>> d['a']=8
>>>> d.sum()
> 18
>>>>

Thank you.  I will go with subclassing method.

-- 
yosuke kimura
Center for Energy and Environmental Resources
The Univ. of Texas at Austin, USA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: trap setting attribute when the attribute is dict

2007-09-03 Thread yosuke
John Machin <[EMAIL PROTECTED]> wrote:
> On Sep 4, 5:47 am, <[EMAIL PROTECTED]> wrote:
>> Arnaud Delobelle <[EMAIL PROTECTED]> wrote:
>> > On Sep 3, 7:00 pm, <[EMAIL PROTECTED]> wrote:
>>
>> >> I want to do something like this.  My class/instance has a dict as a
>> >> property.  I want the instance to catch the change in the dict (change
>> >> in some values, addition/deletion of key/value etc) to be recognized by
>> >> the class instance.
>>
>> >> How can I do this?  Any suggestions are very well appreciated.
>>

[snip]

>>
>> Thank you for suggestion, Arnaud.
>>
>> Since you are discouraging this idea of trigger, may I ask an advice of
>> if my intention was legitimate one or not?
>>
>> My intention was to have a propery 'sum' in my object, and which has sum
>> of all the values() of the dict (i have code to make sure that the value
>> of dict are all numeric).  I could just the propery being calculated
>> everytime the property got __getattr__.  But I thought that it was
>> inefficient to calculate the same number over and over when the value is
>> already known.  So I was thiking of calculating the number only when the
>> dict got modified.
>>
>> I also experimented with the idea of subclassing dict itself to
>> calculate the sum.  Is this what would be better solution?
>>

> And what's wrong with calculating the value when you need it ...

> def thedictsum(self):
> return sum(self.thedict.itervalues())

> How big will the dict be, how often will it be updated, how often will
> the sum be required?

> Have you done timings of any of the options?

Thank you for the post.

I want the code to have fewer lines of code.  That was my biggest
motivation for this.  I have many of this dict with sum, each have <1000
elements.  all of them share the same keys.  I do many
addition/subtraction/divisions by each elements (yes, division makes the
elements not being able to summed).  so in my code i have repeated lines
that works on each elements and then on the sum.  i made a dict to take
care of adding elements by elements.  but i still had two lines of code,
one for dict elements, and one for the sum.

my code was originally in fortran and it has like thousands of lines,
obscuring the mathematics that i want to do.  i need to modify math
often while i use the code (i dont know exactly what math i will need at
this point), so i want to the code to be able to show the math
clearly.  ideally i want to this to be somthing like

c = a + b
d = 1 / c

and each of a, b, c, d knows how to operates on each elements, and also
keep track of the sum.

I think i will settle for extending dict to have sum property and keep
track of it .





> You say you have code to check that the values are numeric; why not
> put this together with maintenance of the sum into a method which
> clients must use to update the dict?

> BTW, my motto:

> "__" == "Danger, Will Robinson!" == "Wrong way, go back" :-)


not quite getting this  :(

> HTH,
> John


-- 
yosuke kimura
Center for Energy and Environmental Resources
The Univ. of Texas at Austin, USA
-- 
http://mail.python.org/mailman/listinfo/python-list


class that keeps track of instances

2007-09-17 Thread yosuke
Hello all,

I'd like some advices from more experienced python users.  I want to
have a class in my python application that does not allow multiple
instance with same "name".  

I want to have a class (call it kls) that behave at least following way:

1) New instance has to have a property called 'name'
2) When instance is attemped to created, e.g., x=kls(name='myname'), and
there already exists an instance with obj.name =='myname', that
pre-existing instance is returned, instead of making new one.  
3) A class property 'all' for class gives me a list of all the
instances.  So kls.all lets me iterates through all instances.
4) When all the hard-link to an instance is deleted, the instance should
be deleted, just like an instance from any regular class does.

My question is if i can find metaclass or something that allows me to
create such class easily.  I tried to search such thing on internet, but
I even don't know how to call this kind of thing.  It is in a sense like
singleton, but less restrictive.

Assuming that I have to write it on my own, what should I do?  I tried
to implement it using weakref.WeakValueDictionary and metaclass, but
instance doesn't disappear when I think it should disappear.  I am also
wondering if it is easier to keeping {name:id(obj)} would be a better
solution.

Any other suggestions are very much appreciated as well.



-- 
yosuke kimura
Center for Energy and Environmental Resources
The Univ. of Texas at Austin, USA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: class that keeps track of instances

2007-09-17 Thread yosuke
[EMAIL PROTECTED] wrote:

> I want to have a class in my python application that does not allow
> multiple instance with same "name".  

Thank you very much for very quick and precise answers to my questions!
input for garbage collector and id are appreciated as well.  I head to
bookstore for the cookbook (O'reily's, right?).  i thought it was too
cryptic but maybe time for met to revisit the book.

-- 
yosuke kimura
Center for Energy and Environmental Resources
The Univ. of Texas at Austin, USA
-- 
http://mail.python.org/mailman/listinfo/python-list