Dynamic Proxy in Python

Thomas Darimont

Erfahrenes Mitglied
Hallo,

hier mal ein kleines Beispiel wie man sich ganz einfach mit Python dynamic Proxies bauen kann.

Schaut mal hier:
Python:
#@author: Thomas.Darimont
import inspect

class Interface(object):
    pass

class IService(Interface):
    def businessOperation(self,arguments):
        """some business operation"""
        pass

class IBubu(Interface):
    def someAction(self,arguments):
        """xxxx"""
        pass

class ServiceImpl(IService,IBubu):
    def businessOperation(self,arguments):
        print str(arguments)
        return str(arguments).upper()
    
    def someAction(self,arguments):
        print "xxx"+str(arguments)
        return str(arguments)[0]

class IInvocationHandler(Interface):
    def invoke(self,proxy,target,methodName,args):
        """invoke..."""
        pass
    
class LoggingInvocationHandler(IInvocationHandler):
    def invoke(self,proxy,target,methodName,args):
        print "before %s" % methodName
        result = getattr(target,methodName)(args)
        print "after %s" % methodName
        return result
    
class InvokableMethod:
    def __init__(self,proxy,invocationTarget,methodName):
        self.methodName = methodName
        self.proxy = proxy
        self.invocationTarget = invocationTarget
    
    def __call__(self,args):
        #print "self=%s, args=%s" % (self,args)
        #return getattr(self.invocationTarget,self.methodName)(args)
        return self.proxy.invocationHandler.invoke(self.proxy,self.invocationTarget,self.methodName,args)
        

class Proxy(object):
   
    def __init__(self):
        pass
    
    @staticmethod
    def createProxy(invocationTarget,interfaces,invocationHandler):
        #print "interfaces: %s" % interfaces
        proxy = Proxy()
        proxy.invocationTarget = invocationTarget
        proxy.invocationHandler = invocationHandler
        proxy.interfaces = interfaces
        proxy.interfaceMethodMap = {}
        for interface in interfaces:
           #print "interfaces to implement %s->%s" % (interface,dir(interface))
           for key in dir(interface):
               #print "checking: %s" % key
               if inspect.ismethod(getattr(interface,key)):
                   #print "adding: %s" % key
                   if not key in proxy.interfaceMethodMap:
                       proxy.interfaceMethodMap[interface] = {key:getattr(interface,key)}
                   else:
                       proxy.interfaceMethodMap[interface][key]=getattr(interface,key)
        return proxy
        
    def __getattr__(self, name):
        for interface in self.interfaces:
            if name in self.interfaceMethodMap[interface]:
                #print "candidate: %s " % candidate.__name__
                return InvokableMethod(self,self.invocationTarget,self.interfaceMethodMap[interface][name].__name__)
            
        return None
    
        

print ServiceImpl().businessOperation("bubu")

serviceProxy = Proxy.createProxy(ServiceImpl(), [IService(),IBubu()],LoggingInvocationHandler())

print serviceProxy.interfaces 

print serviceProxy.businessOperation("test")
print "xxxxxxxxxxxxxxxxxxxxx"
print serviceProxy.someAction("test")

Ausgabe:
Code:
bubu
BUBU
[<__main__.IService object at 0x00A87E90>, <__main__.IBubu object at 0x00A87F90>]
before businessOperation
test
after businessOperation
TEST
xxxxxxxxxxxxxxxxxxxxx
before someAction
xxxtest
after someAction
t

Gruß Tom
 
Zurück