Automatic delegation in Python 3

Thomas Jollans thomas at jollybox.de
Wed Sep 8 16:51:50 EDT 2010


On Wednesday 08 September 2010, it occurred to Steven D'Aprano to exclaim:
> 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.

Yes, special methods are looked up on the type. So you have to make sure the 
type has the methods. 

> 
> 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?
 
Well, yes, you have to implement all the required special methods in the 
Delegate class. But there's no reason you have to do it manually. (I've never 
actually used this in the wild, but it looks like it works)

>>> def makeDelegate(o):
...     T = type(o)
...     class Delegate:
...         def __getattr__(self, name):
...             return getattr(o, name)
...         def __setattr__(self, name, value):
...             setattr(self, name, value)
...     def makewrapper(method):
...         def wrapper(self, *args, **kwargs):
...             return method(o, *args, **kwargs)
...         return wrapper
...     for methodname in dir(T):
...         method = getattr(T, methodname)
...         if methodname not in ('__getattr__', '__setattr__',
...                               '__init__', '__new__', '__class__'):
...             try:
...                 setattr(Delegate, methodname, makewrapper(method))
...             except: pass
...     return Delegate()
... 
>>> D = makeDelegate({'a': 1})
>>> D
{'a': 1}
>>> D['a']
1
>>> D['a'] = 2
>>> D
{'a': 2}
>>> D.get('b')
>>> D['b'] = True
>>> D.get('b')
True
>>> 




More information about the Python-list mailing list