Python использует виртуальный класс для применения универсального паттерна "pipe" - PullRequest
1 голос
/ 16 июня 2011

Я пытаюсь выяснить, можно ли взять следующий код и использовать магию 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, на самом деле нет никаких закулисных методов, как-нибудь взять имя метода и предоставить аргументы и направить их в процесс?

Имеет ли это смысл?Можно ли сделать то же самое на другой стороне?Просто предположите, что все, что происходит, будет иметь вид cmd, args, где cmd - локальный метод?и просто сделай сам. ()?

Поскольку я набираю это, я понимаю, что это, вероятно, сбивает с толку, поэтому, пожалуйста, дайте мне знать, что нуждается в разъяснении.

Спасибо.

Ответы [ 2 ]

4 голосов
/ 16 июня 2011

Вы можете использовать __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"}])
0 голосов
/ 16 июня 2011

Возможно, вы захотите проверить витой каркас .Это не поможет понять, как это сделать самостоятельно, но значительно облегчит написание этого стиля приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...