On Jan 27, 3:16 pm, 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.
What you could do is specialize '__getitem__' (or '__getslice__') so that whenever one of its items is accessed, the item is marked as dirty or the entire list is refreshed. (Unproduced.) def taintlist(list): def __getitem__( self, key ): x= super(taintlist, self).__getitem__( self, key ) self._dirty= True self.refresh() #too early, unfortunately return x ... However, what you are probably after is something like this (unproduced): def taintlist(list): def __getitem__( self, key ): x= super(taintlist, self).__getitem__( self, key ) y= delegate( self, key, x ) return y The 'delegate' class, also unproduced, automatically delegates function calls (including member lookups) to the target. After the delegated call returns, the list is notified-- hence the three arguments to its constructor. (Unproduced.) class delegate: def __getattr__( self, key ): attr= super( delegate, self ).__getattr__( self, key ) deleg= delegate( self.owner, self.ownerkey, attr ) return deleg def __call__( self, *ar, **kw ): res= self.attr( *ar, **kw ) self.owner.markdirty( ) return res I'm not convinced it's possible, but there's a possibility... or something like it. When you call a[0].meth(), three things happen: x= '0' looked up on 'a' y= 'meth' looked up on 'x' z= 'y' called You want control over the last of these parts, so you can call a custom function instead. It becomes increasingly risky as the depth increases, such as if the target class implements custom access, I guess. In the 'delegate' shown, for example, it assumes that the result is callable. You might need: class delegate: def __getattr__( self, key ): attr= super( delegate, self ).__getattr__( self, key ) if not iscallable( attr ): return attr ... #return delegate Further, if the result is callable, that doesn't mean it will necessarily be called. You should be able to tolerate this sequence: x= '0' looked up on 'a' y= 'meth' looked up on 'x' z= attribute looked up on 'y' (instead of 'y' called) Mind if we inquire after your progress? -- http://mail.python.org/mailman/listinfo/python-list