在另一个类

时间:2017-04-28 15:37:41

标签: python python-2.7 multiprocessing python-multiprocessing proxy-classes

我试图让代理类工作,但它并不真正想要工作。我想代理的类如下:

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进程,并添加了一些信息。这个想法是它也可以作为响应发回消息。问题是,消息永远不会发送,我相信这是因为回调过程是另一个创建发布者实例的过程。因此,我试图代理这个类并通过管理器使它可用,但到目前为止它不起作用。有人可以帮我或给我一些提示吗?

亲切的问候 帕特里克

1 个答案:

答案 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__拦截并委托给KlassKlass这里是一个类对象,所以我们代理类本身,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类中,它代理其他类'实例。 Proxyproxied_obj类的一个实例,包含Proxy obj。 *注意,Test就像一个后备选项,只有在找不到属性时才会调用__getattr__。也就是说,如果在__getattr__实例本身中查找了任何属性,或者未找到其类或超类,则会Proxy被触发。

您可以在__getattr__中添加其他方法来扩充代理对象的接口。在3.X和新样式类中,如果代理对象可能需要运算符重载方法:Proxy __add__+进行索引,则需要重新定义__getitem__内的所有重载方法。 {1}}或再次在超类中使内置操作成功:

Proxy

如果您仍然感到困惑:OOP and Delegation: “Wrapper” Proxy Objects

我真的很鼓励你打开Python解释器并试着尝试代码,只是一些小例子。一行代码可能比100个口头单词更好,反之亦然。