On Jan 28, 9:49 am, koranthala <koranth...@gmail.com> wrote: > On Jan 28, 10:39 pm,Reckoner<recko...@gmail.com> wrote: > > > > > On Jan 28, 9:16 am, koranthala <koranth...@gmail.com> wrote: > > > > On Jan 28, 5:42 pm, koranthala <koranth...@gmail.com> wrote: > > > > > On Jan 28, 2:16 am,Reckoner<recko...@gmail.com> wrote: > > > > > > I'm not sure this is possible, but I would like to have > > > > > a list of objects > > > > > > A=[a,b,c,d,...,z] > > > > > > where, in the midst of a lot of processing I might do something like, > > > > > > A[0].do_something_which_changes_the_properties() > > > > > > which alter the properties of the object 'a'. > > > > > > The trick is that I would like A to be mysteriously aware that > > > > > something about the object 'a' has changed so that when I revisit A, > > > > > I will know that the other items in the list need to be refreshed to > > > > > reflect the changes in A as a result of changing 'a'. > > > > > > Even better would be to automatically percolate the subsequent changes > > > > > that resulted from altering 'a' for the rest of the items in the list. > > > > > Naturally, all of these items are related in some parent-child > > > > > fashion. > > > > > > that might be a lot to ask, however. > > > > > > Any advice appreciated. > > > > > I think Python Cookbook has a recipe which deals with this. > > > > - 6.12 Checking an Instance for Any State Change. > > > > Were you able to get this? If not, let me know. I will try to type it > > > in here - (it is a big recipe, so not doing it now) > > > Actually, I have the python cookbook, but cannot find the recipe you > > mention. maybe I have an older version? > > > thanks. > > Mine is 2nd Edition.
for posterity's sake, here's the recipe in question: import copy class ChangeCheckerMixin(object): containerItems = {dict: dict.iteritems, list: enumerate} immutable = False def snapshot(self): ''' create a "snapshot" of self's state -- like a shallow copy, but recursing over container types (not over general instances: instances must keep track of their own changes if needed). ''' if self.immutable: return self._snapshot = self._copy_container(self.__dict__) def makeImmutable(self): ''' the instance state can't change any more, set .immutable ''' self.immutable = True try: del self._snapshot except AttributeError: pass def _copy_container(self, container): ''' semi-shallow copy, recursing on container types only ''' new_container = copy.copy(container) for k, v in self.containerItems[type(new_container)] (new_container): if type(v) in self.containerItems: new_container[k] = self._copy_container(v) elif hasattr(v, 'snapshot'): v.snapshot( ) return new_container def isChanged(self): ''' True if self's state is changed since the last snapshot ''' if self.immutable: return False # remove snapshot from self.__dict__, put it back at the end snap = self.__dict__.pop('_snapshot', None) if snap is None: return True try: return self._checkContainer(self.__dict__, snap) finally: self._snapshot = snap def _checkContainer(self, container, snapshot): ''' return True if the container and its snapshot differ ''' if len(container) != len(snapshot): return True for k, v in self.containerItems[type(container)](container): try: ov = snapshot[k] except LookupError: return True if self._checkItem(v, ov): return True return False def _checkItem(self, newitem, olditem): ''' compare newitem and olditem. If they are containers, call self._checkContainer recursively. If they're an instance with an 'isChanged' method, delegate to that method. Otherwise, return True if the items differ. ''' if type(newitem) != type(olditem): return True if type(newitem) in self.containerItems: return self._checkContainer(newitem, olditem) if newitem is olditem: method_isChanged = getattr(newitem, 'isChanged', None) if method_isChanged is None: return False return method_isChanged( ) return newitem != olditem if __name__ == '__main__': class eg(ChangeCheckerMixin): def __init__(self, *a, **k): self.L = list(*a, **k) def __str__(self): return 'eg(%s)' % str(self.L) def __getattr__(self, a): return getattr(self.L, a) x = eg('ciao') print 'x =', x, 'is changed =', x.isChanged( ) # emits: x = eg(['c', 'i', 'a', 'o']) is changed = True # now, assume x gets saved, then...: x.snapshot( ) print 'x =', x, 'is changed =', x.isChanged( ) # emits: x = eg(['c', 'i', 'a', 'o']) is changed = False # now we change x...: x.append('x') print 'x =', x, 'is changed =', x.isChanged( ) # emits: x = eg(['c', 'i', 'a', 'o', 'x']) is changed = True -- http://mail.python.org/mailman/listinfo/python-list