I'm looking for way to pass method calls through from an object (wrapper) to a member variable of an object (wrappee). There are potentially many methods that need to be externalised, so a way to do this without changing the interface of the wrapper when adding a method to the wrappee would be helpful.
def __init__(self, wrappee):
self.wrappee = wrappee
o2 = Wrappee()
o1 = Wrapper(o2)
o1.foo() # -> 42
o1.bar() # -> 12
o1.<any new function in Wrappee>() # call directed to this new function
A somewhat elegant solution is by creating an "attribute proxy" on the wrapper class:
class Wrapper(object): def __init__(self, wrappee): self.wrappee = wrappee def foo(self): print 'foo' def __getattr__(self, attr): try: super(Wrapper, self).__getattr__() except AttributeError as e: return getattr(self.wrappee, attr) class Wrappee(object): def bar(self): print 'bar' o2 = Wrappee() o1 = Wrapper(o2) o1.foo() o1.bar()
all the magic happens on the
__getattr__ method of the
Wrapper class, which will try to access the method or attribute on the
Wrapper instance, and if it doesn't exist, it will try on the wrapped one.
if you try to access an attribute that doesn't exist on either classes, you will get this:
o2.not_valid Traceback (most recent call last): File "so.py", line 26, in <module> o2.not_valid File "so.py", line 15, in __getattr__ raise e AttributeError: 'Wrappee' object has no attribute 'not_valid'