...What i'm trying to do is tie special methods of a "proxy" instance to another instance:
new style classes:
def test2(): print "test2" class Container(object): def __init__( self, data ): self.data = data # self.__dict__["__getitem__"] = self.data.__getitem__ self.__setattr__( "__getitem__", self.data.__getitem__ ) data = range(10) c = Container(data) print print c.__getitem__(3) # works OK print c[3] # fails
because __getitem__ is looked up in the class, not the instance dictionary
I get a "TypeError: unindexable object". It seems that c[] does not call __getitem__ in this case.
The plot thickens, however, when one tries the following:
def test3(): data = range(10) c = type( "Container", (), { "__getitem__":data.__getitem__ } )() print "test3" print c[3]
Here you've created an entry in the class dictionary, just like writing data = range(10) class Container(object): __getitem__ = data.__getitem__
but, this probably doesn't help you much if you want the method to delegate to an attribute of the instance, since the instance is unavailable at class definition time
So, one solution, is to use create a delegating descriptor, like so:
class Delegate(object): def __init__(self, attrname): self.attrname = attrname def __get__(self, obj, cls): if isinstance(obj, cls): # Note that the attribute is looked up on obj._data return getattr(obj._data, self.attrname) else: return self
class Example(object): __getitem__ = Delegate("__getitem__")
def __init__(self, delegate): self._data = delegate
>>> e = Example(range(10)) >>> e[3] 3
Michael
-- http://mail.python.org/mailman/listinfo/python-list