2013-01-14 36 views
4

我试图在使用multiprocessing模块的进程之间传递自定义Queue。问题是我没有把所有的方法都传递给对方。根据文档。Python多处理传递参考

代理对象具有调用其对象的相应方法的方法(尽管并非指代的每个方法都必须通过代理可用)。代理人通常可以以与其所指对象相同的方式使用

但它没有说明为什么或解决方法。我想知道是否有人知道这样做的一种方式。

这是我想要做的一个小例子。

服务器:

from multiprocessing.managers import BaseManager 
from Queue import Queue 


class KeyHandler(Queue): 

    def __init__(self, elements=[]): 
     Queue.__init__(self) 

     for element in elements: 
      self.put(element) 

    def __iter__(self): 
     return iter(self.get, object()) 

    def __call__(self): 
     return self 


class QueueManager(BaseManager): 
    pass 

keyhandler = KeyHandler(range(10)) 


QueueManager.register('keyhandler', callable=keyhandler) 
manager = QueueManager(address=('', 50000), authkey='foobar') 
server = manager.get_server() 
server.serve_forever() 

客户:

from multiprocessing.managers import BaseManager 


class QueueManager(BaseManager): 
    pass 


QueueManager.register('keyhandler') 
manager = QueueManager(address=('', 50000), authkey='foobar') 
manager.connect() 

keyhandler = manager.keyhandler() 

for elem in keyhandler: 
    print elem 

回溯:

Traceback (most recent call last): 
    File "client2.py", line 14, in <module> 
    for elem in keyhandler: 
TypeError: 'AutoProxy[keyhandler]' object is not iterable 

__call__方法可行,但__iter__方法不适用。我可以强制/解决这个问题吗?

+0

也许你需要添加一个'暴露= [ '__ ITER __']'关键字参数给服务器中的'QueueManager.register()'调用。 – martineau

回答

1

使用代理。在客户端添加这个类声明(连同进口BaseProxy):

class KeyHandlerProxy(BaseProxy): 
    _exposed_ = ('next', 'get') 

    def __iter__(self): 
     return self 

    def next(self): 
     o = self._callmethod('get') 
     if object() == o: 
      raise StopIteration 
     return o 

,并更改register(客户端),以这样的:

QueueManager.register('keyhandler', proxytype=KeyHandlerProxy) 
+0

你不需要'_exposed_'字段 – kerim