Delegation in old-style classes worked fine: # Python 2.6 >>> class Delegate: ... def __init__(self, x): ... self.__dict__['x'] = x ... def __getattr__(self, name): ... return getattr(self.x, name) ... def __setattr__(self, name, value): ... setattr(self.x, name, value) ... >>> obj = Delegate({}) >>> obj[1] = None >>> obj {1: None}
But when I try the equivalent recipe with a new-style class, it behaves differently: >>> class Delegate2(object): ... def __init__(self, x): ... self.__dict__['x'] = x ... def __getattr__(self, name): ... return getattr(self.x, name) ... def __setattr__(self, name, value): ... setattr(self.x, name, value) ... >>> obj = Delegate2({}) >>> obj <__main__.Delegate2 object at 0x8f6130c> Okay, I get that one... because I'm inheriting from object, __getattr__ picks up object's __str__ method and uses that. But then there's this: >>> obj[1] = 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'Delegate2' object does not support item assignment But these work: >>> obj.__setitem__ <method-wrapper '__setitem__' of dict object at 0xb7c6902c> >>> obj.__setitem__(1, None) >>> obj.x {1: None} What's going on here? I *think* this has something to do with special double-underscore methods being looked up on the class, not the instance, for new-style classes, but I'm not entirely sure. Unfortunately, I need to use delegation, not inheritance, and I need to use a new-style class, since I will be using Python 3. How can I do automatic delegation in Python 3? Is my only hope to give up on the elegance of automatic delegation, and code all the special methods as manual delegation? class Delegate2(object): def __setitem__(self, key, value): self.x[key] = value # and so on for everything else I care about... -- Steven -- http://mail.python.org/mailman/listinfo/python-list