On Jan 27, 9:46 pm, Steven D'Aprano <ste...@remove.this.cybersource.com.au> wrote: > On Tue, 27 Jan 2009 13:16:36 -0800, Reckoner 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'. > > Can't be done if A is a built-in list, probably can't be done entirely > generically, but you can probably do it in a cooperative manner. > > class TaintList(list): > tainted = False > def taint(self): > self.tainted = True > def untaint(self): > self.tainted = False > > A = TaintList() > > import functools > def taint(parent): > def decorator(func): > @functools.wraps(func) > def f(*args, **kwargs): > parent.taint() > return func(*args, **kwargs) > return f > return decorator > > class TaintAwareThing(object): > def __init__(self): > self.attr = 0 > @taint(A) > def change_attribute(self, x): > self.attr = x > > >>> x = TaintAwareThing() > >>> y = TaintAwareThing() > >>> z = TaintAwareThing() > > >>> A.extend([x, y, z]) > >>> A.tainted > False > >>> x.change_attribute(5) > >>> A.tainted > > True > > Here is a second approach: create a proxy class TaintThing that wraps > whatever object you want, using delegation: > > class TaintThing(object): > parent = A > def __init__(self, obj): > self.__dict__['_proxy'] = obj > def __getattr__(self, attr): > return getattr(self._proxy, attr) > def __setattr__(self, attr, value): > setattr(self._proxy, attr, value) > self.parent.taint() > > Now change TaintList to automatically wrap anything stored in it: > > # untested > class TaintList(list): > def append(self, obj): > list.append(self, TaintThing(obj)) > # similar for __setitem__, extend, insert > > -- > Steven
thanks for your reply. For the second case where > class TaintThing(object): > parent = A > def __init__(self, obj): > self.__dict__['_proxy'] = obj > def __getattr__(self, attr): > return getattr(self._proxy, attr) > def __setattr__(self, attr, value): > setattr(self._proxy, attr, value) > self.parent.taint() you have told it that parent is 'A'. Shouldn't that be passed to it somehow in the following: > # untested > class TaintList(list): > def append(self, obj): > list.append(self, TaintThing(obj)) > # similar for __setitem__, extend, insert I apologize. I am probably missing something. This is getting pretty advanced for me. Thanks again. -- http://mail.python.org/mailman/listinfo/python-list