On 9/8/2010 9:58 AM, Steven D'Aprano wrote:
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
Since you are not setting a attribute, I was initially surprised that
this worked. Then I remembered that this is executed for old-style
classes as
obj.__getattr__('__setitem__')(1,None)
and that __setattr__ above is not involved.
This is possible because old-style user classes were a world apart form
builtin types. Once user-classes were integrated into the builting
class/type hierarchy, they had to follow the same rules as the latter.
One problem is that classes are also instances of their metaclass. This
is somewhat explained in 3.3.8 'Special method lookup' (which I have
read at least 3 times before understanding).
As you discovered, this is not a complete win. The bottom line of 3.3.8:
"Bypassing the __getattribute__() machinery in this fashion provides
significant scope for speed optimisations within the interpreter, at the
cost of some flexibility in the handling of special methods (the special
method must be set on the class object itself in order to be
consistently invoked by the interpreter)."
You are seeing the cost.
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?
Based on the above, it seems so. But I would search a bit more for
delegation and proxy object and python 3 to see what others have done.
--
Terry Jan Reedy
--
http://mail.python.org/mailman/listinfo/python-list