Python使用虚拟类来应用通用的“管道”模式

时间:2011-06-16 13:41:45

标签: python python-2.7

我试图找出是否可以采用以下代码,并使用python的魔力来简化代码。

现在我有一个命令接口,它位于一堆python子进程之上。当我需要与子进程的I管道命令进行通信时。基本上它归结为字符串命令和参数字典。

这是重复的模式(为简单起见,我显示了1,但实际上,对于不同的过程重复了7次)

创建流程:

class MasterProcess(object):
 def __init__(self):
  self.stop = multiprocessing.Event()

  (self.event_generator_remote, self.event_generator_in)
       =     multiprocessing.Pipe(duplex=True)
  self.event_generator= Process(target=self.create_event_generator, 
                            kwargs={'in':   self.event_generator_remote} 
                    )
  self.event_generator.start()

 def create_event_generator(self, **kwargs):
      eg= EventGenerator()
      in_pipe = kwargs['in']

      while(not self.stop.is_set()):
            self.stop.wait(1)
            if(in_pipe.poll()):
               msg = in_pipe.recv()
               cmd = msg[0]
               args = msg[1]
               if cmd =='create_something':
                   in_pipe.send(eg.create(args))
               else:
                   raise NotImplementedException(cmd)

然后在命令界面上只是向命令流程输入命令:

 mp.MasterProcess()
 pipe =  mp.event_generator_remote

 >>cmd:  create_something args

 #i process the above and then do something like the below 

 cmd = "create_something"
 args = {
      #bah
 }
 pipe.send([command, args])

 attempt = 0
 while(not pipe.poll()):
    time.sleep(1)
    attempt +=1
    if attempt > 20:
        return None
     return pipe.recv()

我想要移动的更多是远程外观类型的交易,客户端只是调用一般的方法,我将该调用转换为上述。

例如,新命令看起来像:

mp.MasterProcess()
mp_proxy = MasterProcessProxy(mp.event_generator_remote)
mp_proxy.create_something(args)

所以我的虚拟类是MasterProcessProxy,幕后真的没有方法拿某个方法名称,并提供args并将它们传递给进程?

这有意义吗?是否有可能在另一边做同样的事情?假设管道中的任何内容都将采用cmd格式,其中cmd是本地方法吗?并做一个自我。()?

当我打字时,我明白它可能令人困惑,所以请告诉我需要澄清的内容。

感谢。

2 个答案:

答案 0 :(得分:4)

您可以使用__getattr__为存根类创建代理方法:

class MasterProcessProxy(object):

    def __init__(self, pipe):
        self.pipe = pipe

    # This is called when an attribute is requested on the object.
    def __getattr__(self, name):
        # Create a dynamic function that sends a command through the pipe
        # Keyword arguments are sent as command arguments.
        def proxy(**kwargs):
            self.pipe.send([name, kwargs])
        return proxy

现在您可以根据需要使用它:

mp.MasterProcess()
mp_proxy = MasterProcessProxy(mp.event_generator_remote)
mp_proxy.create_something(spam="eggs", bacon="baked beans")
# Will call pipe.send(["create_something", {"spam":"eggs", "bacon":"baked beans"}])

答案 1 :(得分:0)

您可能想查看twisted framework。这不会打算弄清楚如何自己完成,但会使这种应用程序的编写变得更加容易。