Generic optional delegation: is it possible?

Eric Brunel eric.brunel at pragmadev.com
Thu Mar 13 10:52:04 EST 2003


Hi all,

I just stumbled on a problem and I can't see a way of doing it in an "elegant" 
way. Here it is: I have objects that may have another object attached to them. 
If this object is actually attached, I want all methods to be delegated to it. 
Otherwise, I want the object to call the methods on its super-class.

For example:

---------------------------------------
class Delegate:
   def m(self):
     print "Delegate"

class SuperClass:
   def m(self):
     print "SuperClass"

class Delegating(SuperClass):
   def __init__(self, delegate=None):
     self.__delegate = delegate
   def m(self):
     if self.__delegate is not None:
       self.__delegate.m()
     else:
       SuperClass.m(self)

d = Delegate()
o1 = Delegating(d)
o2 = Delegating()
o1.m()
o2.m()
---------------------------------------

This does what I want: o1 has a delegate, and when I call m on it, it calls m on 
the delegate d. So it prints out "Delegate". o2 doesn't have a delegate, so the 
method m called is the super-class's one, and it prints out "SuperClass"

The problem is that I have gazillions of methods like m, and that I'd like to 
define this behaviour generically: whenever I call a method, if object has a 
delegate, call method on delegate; otherwise call super-class's method. So I tried:

---------------------------------------
class Delegate:
   def m(self):
     print "Delegate"

class SuperClass:
   def m(self):
     print "SuperClass"

class Delegating(SuperClass):
   def __init__(self, delegate=None):
     self.__delegate = delegate
   def __getattr__(self, attr):
     if self.__delegate is not None:
       return getattr(self.__delegate, attr)
     else:
       return getattr(SuperClass, attr)

d = Delegate()
o1 = Delegating(d)
o2 = Delegating()
o1.m()
o2.m()
---------------------------------------

But it doesn't work: of course, object o1 *has* an attribute m (the method 
inherited from SuperClass), so __getattr__ doesn't get called.

Any ideas on how this can be achieved without having to type again all methods 
on my sub-class?

TIA
-- 
- Eric Brunel <eric.brunel at pragmadev.com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com





More information about the Python-list mailing list