then it will be the same as writing
x.bar
x.foo
for any method in class x (with the possible exception of 'bar').
The first few times I wanted to print out a data structure for
debugging purposes. Most recently it was to save a data structure to
allow "undo" operations. I've realized that this is a generalized
problem and I was hoping that someone could point me to the correct
hook to accomplish this (python seems to have a hook for everything).
Perhaps you want __getattribute__ on a new-style class?
--
Michael Hoffman
Perhaps I do. The docs say that __getattribute__ is called on all
attribute references, so I tried to make an undoable list as follows:
% cat Undoable.py
class Undoable(object):
def __init__(self, superclass):
self.superclass = superclass
print "__init__"
def __getattribute__(self, name):
print "__getattribute__"
self.SaveState(self)
self.superclass.__getattribute__(self, name)
def SaveState(self):
print "SaveState"
def RestoreState(self):
pass
l = Undoable(list)
l = [1, 2, 3]
print l.count(1)
% python Undoable.py
__init__
1
It appears that __init__ in Undoable is called, count() in list is
called, but not __getattribute__ or SaveState in Undoable.
What don't I understand?
> l = Undoable(list)
> l = [1, 2, 3]
You just rebound l, so it no longer refers to an Undoable, it
refers to a list. This design won't work, you need something
more like:
l = Undoable([1, 2, 3])
There were a few other pitfalls in your design... Here,
try something like this instead:
class SurrogateNotInitedError(exceptions.AttributeError):
pass
class Surrogate(object):
"""
the data is stored in _data
>>> list1 = [0, 1, 2, 3]
>>> list2 = [4, 5, 6, 7]
>>> surrogate = Surrogate(list1)
>>> surrogate.reverse()
>>> list1
[3, 2, 1, 0]
>>> surrogate._data = list2
>>> surrogate.append(8)
>>> list2
[4, 5, 6, 7, 8]
"""
def __init__(self, data):
self._data = data
def __getattr__(self, name):
if name == "_data":
raise SurrogateNotInitedError, name
else:
try:
return getattr(self._data, name)
except SurrogateNotInitedError:
raise SurrogateNotInitedError, name
You can modify this to make an UndoableSurrogate with appropriate saving
of state. Note the use of __getattr__ instead of __getattribute__. The
latter is not needed since there are not any attributes defined on
Surrogate instead.
--
Michael Hoffman