Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proxy object in Python

Tags:

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.

class Wrapper(object)
  def __init__(self, wrappee):
    self.wrappee = wrappee

  def foo(self):
    return 42

class Wrappee(object):
  def bar(self):
    return 12

o2 = Wrappee()
o1 = Wrapper(o2)

o1.foo() # -> 42
o1.bar() # -> 12
o1.<any new function in Wrappee>() # call directed to this new function 

It would be great if this call redirection is "fast" (relative to a direct call, i.e. not adding too much overhead).

like image 824
orange Avatar asked Sep 29 '14 02:09

orange


People also ask

What are proxy objects?

A proxy object acts as an intermediary between the client and an accessible object. The purpose of the proxy object is to monitor the life span of the accessible object and to forward calls to the accessible object only if it is not destroyed.

What is proxy method?

The Proxy method is Structural design pattern that allows you to provide the replacement for an another object. Here, we use different classes to represent the functionalities of another class. The most important part is that here we create an object having original object functionality to provide to the outer world.

What is lazy object proxy?

ObjectProxy just forwards the method calls to the target object. In other words, you use lazy-object-proxy when you only have the object way later and you use wrapt. ObjectProxy when you want to override few methods (by subclassing) and forward everything else to the target object.

What is proxy in coding?

In computer programming, the proxy pattern is a software design pattern. A proxy, in its most general form, is a class functioning as an interface to something else.


1 Answers

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):
        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'
like image 78
Rafael Barros Avatar answered Oct 23 '22 13:10

Rafael Barros