I'm trying to get a proxy class working, but it does not really want to work. The class that I want to proxy is the following:
import zmq
class ZmqPublish():
def __init__(self):
self.context = None
self.pub_socket = None
def setup(self, addr):
self.context = zmq.Context()
if isinstance(addr, str):
addr = addr.split(':')
host, port = addr if len(addr) == 2 else (addr[0], None)
self.pub_socket = self.context.socket(zmq.PUB)
self.pub_socket.bind('tcp://%s:%s' % (host, port))
def send(self, msg_type, msg):
self.pub_socket.send_multipart([msg_type, msg])
This simply starts a publisher and has the ability to send messages. Then I have another class that takes care of storing data and sending messages as well as a kind of reply:
from multiprocessing import Manager
from multiprocessing.managers import BaseManager
import zmq_publish
class publishManager(BaseManager):
pass
publishManager.register('zmq_publish.ZmqPublish', zmq_publish.ZmqPublish)
class Storage:
def __init__(self):
self.manager = Manager()
self.dict = self.manager.dict()
# Additional variables
self.host = '127.0.0.1'
self.port = 5555
self.bind_addr = (self.host, self.port)
self.publishManager = Storage.publishManager()
self.publishManager.start()
self.publishManager.setup(self.bind_addr)
def setup(self):
# Set up zmq subscriber with callbacks
def add(self, msg):
self.dict[msg] = 0
self.publishManager.send('type', msg)
For example the add function is given to a zmq process as a callback and it adds some information. The idea is that it can also send a message back as a response. The problem is, that the message is never send and I believe it is due to the fact that the callback process is another one than the one who created the publisher instance. Thus I am trying to proxy this class and make it available through a manager, but so far it does not work. Can somebody help me or give me some hints?
Kind regards Patrick
I haven't understood your question totally. I'll provide you with a hint that hopefully will assist in achieving the task. You can proxy objects by overloading
__getattr__for undefined attributes accesses and/or__getattribute__for all attribute accesses.Now any attribute that's not defined at
Proxywill be intercepted by__getattr__and delegated toKlass.Klasshere is a class object so we proxy the class itself,Klasscan also be an actual instance of a class. Basically,Proxydelegates only undefined attribute fetches toklass. Hence, when you access an attribute that's not available forProxy, doesn't exist inProxyor its instances,__getattr__gets triggered automatically and will delegate your request to the wrapped/embedded objectklass. For intercepting all attribute fetches you would use__getattribute__instead of__getattr__and in addition to that you might need to useobject.__getattribute__to avoid recursion inside__getattribute__, because anyself.attrinside your proxy methods will trigger your class's__getattribute__.Edit: How to use the
Proxyclass:If you would like to to proxy an object of another class, one way to achieve this:
As you can see,
addandmulmethod doesn't actually exist inProxyclass which proxies other classes' instances.proxied_objis an instance ofProxyclass with a wrappedTestobj. *Notice,__getattr__is like a fallback option, only when attributes are not found,__getattr__gets called. That is, if any attribute was looked up in theProxyinstance itself or its class or superclasses was not found, then__getattr__gets triggered.You could add other methods in
Proxyto augment the the interface of the proxied object. In 3.X and new-style classes, if your proxied object may require operator overloading methods:__add__for+or__getitem__for indexing, you need to redefine all the overloading methods insideProxyor in a superclass again so builtin operations will succeed:If you're still confused: OOP and Delegation: “Wrapper” Proxy Objects
I really encourage you to open Python interpreter and try to experiment with code, just small examples. One line of code might be better than 100 spoken words and vice versa.