self-aware list of objects able to sense constituent member alterations?
Steven D'Aprano
steven at REMOVE.THIS.cybersource.com.au
Wed Jan 28 00:46:46 EST 2009
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
More information about the Python-list
mailing list