【问题标题】:Python use a virtual class to apply a generic "pipe" patternPython 使用虚拟类来应用通用的“管道”模式
【发布时间】:2011-06-16 13:41:44
【问题描述】:

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

现在我有一个位于一堆 python 子进程之上的命令界面。当我需要与子进程通信时,我通过管道将命令发送给它们。基本上它归结为一个字符串命令和一个参数字典。

这是重复的模式(为了简单起见,我展示了 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 、 args 的形式出现,其中 cmd 是本地方法?做一个 self.() ?

在我输入此内容时,我知道这可能令人困惑,所以请让我知道需要澄清的地方。

谢谢。

【问题讨论】:

    标签: python python-2.7


    【解决方案1】:

    您可以使用__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"}])
    

    【讨论】:

    • 我感觉会很简单,我现在正在测试。
    • 这非常有效。而且我几乎利用相同类型的东西来执行服务器端方法调用。
    【解决方案2】:

    您可能想查看twisted framework。这不会比自己弄清楚如何做要好,但会使编写这种风格的应用程序变得容易得多。

    【讨论】:

    • 我一切正常,我只是不喜欢我必须做所有这些无用的映射。
    猜你喜欢
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 2023-04-09
    • 2017-10-22
    • 2018-08-20
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多