我试图让代理类工作,但它并不真正想要工作。我想代理的类如下:
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])
这只是启动发布者并具有发送消息的能力。 然后我有另一个负责存储数据和发送消息的类以及一种回复:
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)
例如,add
函数作为回调被赋予zmq进程,并添加了一些信息。这个想法是它也可以作为响应发回消息。问题是,消息永远不会发送,我相信这是因为回调过程是另一个创建发布者实例的过程。因此,我试图代理这个类并通过管理器使它可用,但到目前为止它不起作用。有人可以帮我或给我一些提示吗?
亲切的问候 帕特里克
答案 0 :(得分:1)
我完全不了解你的问题。我将为您提供一些希望有助于完成任务的提示。您可以通过为未定义的属性访问重载__getattr__
和/或为{em>所有属性访问重载__getattribute__
来代理对象。
class Proxy:
def __init__(self, Klass):
self.Klass = Klass # Save/embed original class/object
def __getattr__(self, name): # On undefined attr fetches only
...
return getattr(self.Klass, name) # Delegate to Klass/ could be an obj too
....
现在Proxy
未定义的任何属性都会被__getattr__
拦截并委托给Klass
。 Klass
这里是一个类对象,所以我们代理类本身,Klass
也可以是类的实际实例。基本上,Proxy
仅将未定义的属性提取委托给klass
。因此,当您访问Proxy
不可用的属性时,Proxy
或其实例中不存在,__getattr__
会自动触发并委派您的请求到包装/嵌入对象klass
。要拦截所有属性提取,您可以使用__getattribute__
而不是__getattr__
,除此之外,您可能需要使用object.__getattribute__
来避免__getattribute__
内的递归,因为任何{{1}在您的代理方法内部将触发您的班级self.attr
。
编辑:如何使用__getattribute__
类:
如果您想代理另一个类的对象,可以采用一种方法:
Proxy
正如您所看到的,class Proxy:
# Proxy objects of other classes
def __init__(self, obj):
self.obj = obj
def __getattr__(self, attr):
return getattr(self.obj, attr) # Run only on undefined attribute accesses
class Test:
data = 'some data'
def __init__(self, x, y):
self.x = x
self.y = y
def add(self):
return self.x + self.y
def mul(self):
return self.x * self.y
test_obj = Test(3, 4)
proxied_obj = Proxy(test_obj) # Delegate some operations to test_obj
proxied_obj.add() # Calls Proxy.__getattr__
print(proxied_obj.mul()) # Calls Proxy.__getattr__
和add
方法实际上并不存在于mul
类中,它代理其他类'实例。 Proxy
是proxied_obj
类的一个实例,包含Proxy
obj。 *注意,Test
就像一个后备选项,只有在找不到属性时才会调用__getattr__
。也就是说,如果在__getattr__
实例本身中查找了任何属性,或者未找到其类或超类,则会Proxy
被触发。
您可以在__getattr__
中添加其他方法来扩充代理对象的接口。在3.X和新样式类中,如果代理对象可能需要运算符重载方法:Proxy
__add__
或+
进行索引,则需要重新定义__getitem__
内的所有重载方法。 {1}}或再次在超类中使内置操作成功:
Proxy
如果您仍然感到困惑:OOP and Delegation: “Wrapper” Proxy Objects
我真的很鼓励你打开Python解释器并试着尝试代码,只是一些小例子。一行代码可能比100个口头单词更好,反之亦然。