Reputation: 2981
I have a object like:
class Foo(object):
def __init__(self,instance):
self.instance = instance
with
>>> instance = SomeOtherObject()
>>> f = Foo(instance)
I want to be able to do
>>> f.some_method()
and have the following call,
>>> f.instance.some_method()
For complicated reasons, I cannot simply chain the attributes as in the above. I need to dynamically create an instance function on f
with the same function signature as the embedded instance
. That is, I need to do f.some_method()
and then dynamically create the some_method
instance-method for the f
instance when it is invoked that pushes some_method
down to the embedded object instance
.
I hope that made sense. This is for Python 2.7. Any help appreciated.
Upvotes: 0
Views: 1033
Reputation: 184270
Write a __getattr__()
method for your proxy class. This will be called when an attribute is accessed that doesn't exist on your instance. Return your contained object's attribute of the same name (or a wrapper if you insist, but there's no need if you just want to call the contained object's method and don't need to do anything else). Bonus: works with data as well as callables.
def __getattr__(self, name):
return getattr(self.instance, name)
Does not work with __
methods, however.
Upvotes: 3
Reputation: 58563
You should look at the wrapt
module. It is purpose built for creating transparent object proxy where you can selectively override certain aspects of the wrapped object. For example:
class Test(object):
def some_method(self):
print 'original'
import wrapt
proxy = wrapt.ObjectProxy(Test())
proxy.some_method()
print
class TestWrapper(wrapt.ObjectProxy):
def some_method(self):
self.__wrapped__.some_method()
print 'override'
wrapper = TestWrapper(Test())
wrapper.some_method()
This yields:
original
original
override
The default behaviour of the ObjectProxy
class is to proxy all method calls or attribute access. Updating attributes via the proxy will also update the wrapped object. Works for special __
methods and lots of other stuff as well.
For details on wrapt
see:
Specific details on the object proxy can be found in:
There are so many traps and pitfalls with doing this correctly, so recommended you use wrapt
if you can.
Upvotes: 1