How do I use the Proxy recipe ?

English, Mark Mark.English at rbccm.com
Fri Dec 21 07:08:04 EST 2007


The proxy recipe
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252151 (*) by
Goncalo Rodrigues shows how to wrap an existing instance of a new or old
style class in a "Proxy" instance.
I'm just wondering what a programmer does once that's been achieved ? Is
he or she supposed to patch the generated proxy instance (or proxy
class) after it's been created ?

I may have missed the point, but I ended up allowing the caller to
"proxy()" to specify a base class. Code included below. Original code
from the recipe, all mistakes are mine. Proxy renamed to ProxyBase.

Thanks,
Mark

class ProxyBase(object):
    """base clas for all proxies"""
    def __init__(self, obj):
        super(ProxyBase, self).__init__(obj)
        self._obj = obj

    def __getattr__(self, attrib):
        return getattr(self._obj, attrib)

def make_binder(unbound_method):
    def f(self, *a, **k): return unbound_method(self._obj, *a, **k)

known_proxy_classes = {}

def proxy(obj, klassProxy=None, *specials):
    """factory-function for a proxy able to delegate special methods"""
    if klassProxy is None: #If no proxy class provided
        klassProxy = ProxyBase
    #do we already have a suitable customized class around ?
    obj_cls = obj.__class__
    key = obj_cls, klassProxy, specials
    cls = known_proxy_classes.get(key)
    if cls is None:
        #we don't have a suitable class around, so let's make it
        cls = type("%sProxy" % obj_cls.__name__, (klassProxy,), {})
        for name in specials:
            name = '__%s__' % name
            unbound_method = getattr(obj_cls, name)
            setattr(cls, name, make_binder(unbound_method))
        #also cache it for the future
        known_proxy_classes[key] = cls
    #instantiate and return the needed proxy
    return cls(obj)

class FooProxy(ProxyBase):
    def fn2(self):
        print 'Proxy foo2'
        print 'Proxy calling base...'
        self._obj.fn2()
        print 'Proxy called base...'

if __name__ == '__main__':
    #Quick example
    class Foo(object):
        def fn1(self): print 'Foo fn1'
        def fn2(self): print 'Foo fn2'
        def fn3(self): print 'Foo fn3'
    f = Foo()
    pf = proxy(f, FooProxy)
    pf.fn1()
    pf.fn2()

---Output---
Foo fn1
Proxy foo2
Proxy calling base...
Foo fn2
Proxy called base...

*I'm actually using the Python Cookbook, 2d ed., by Alex Martelli, Anna
Martelli Ravenscroft, and David Ascher (O'Reilly Media, 2005)
0-596-00797-3 recipe 6.6
______________________________________________________________________

This email is intended only for the use of the individual(s) to whom it is addressed and may be privileged and confidential.
Unauthorised use or disclosure is prohibited.If you receive This e-mail in error, please advise immediately and delete the original message.
This message may have been altered without your or our knowledge and the sender does not accept any liability for any errors or omissions in the message.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20071221/edb3cb46/attachment.html>


More information about the Python-list mailing list