Лучший способ смешивать и сочетать компоненты в приложении Python - PullRequest
4 голосов
/ 07 февраля 2011

У меня есть компонент, который использует простой модуль pub / sub, который я написал как очередь сообщений. Я хотел бы попробовать другие реализации, такие как RabbitMQ. Тем не менее, я хочу, чтобы это изменение бэкэнда было настраиваемым, чтобы я мог переключаться между моей реализацией и сторонними модулями для обеспечения чистоты и тестирования.

Очевидный ответ:

  1. Считать файл конфигурации
  2. Создание объекта изменяемых настроек / dict
  3. Измените целевой компонент, чтобы лениво загрузить указанную реализацию.

что-то вроде:

# component.py
from test.queues import Queue

class Component:

  def __init__(self, Queue=Queue):
      self.queue = Queue()

  def publish(self, message):
      self.queue.publish(message)

# queues.py
import test.settings as settings

def Queue(*args, **kwargs):
  klass = settings.get('queue')
  return klass(*args, **kwargs)

Не уверен, что init должен принимать класс Queue, я думаю, это поможет легко определить очередь, используемую при тестировании.

Еще одна мысль, которая у меня была, была что-то вроде http://www.voidspace.org.uk/python/mock/patch.html, хотя, похоже, что это станет грязным. Достоинством было бы то, что мне не пришлось бы изменять код для поддержки замены компонента.

Любые другие идеи или анекдоты приветствуются.

РЕДАКТИРОВАТЬ: Исправлен отступ.

1 Ответ

2 голосов
/ 08 февраля 2011

Одна вещь, которую я сделал раньше, - это создание общего класса, от которого наследуется каждая конкретная реализация. Затем есть спецификация, которой легко следовать, и каждая реализация может избежать повторения определенного кода, которым они все поделятся.

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

class SaverTemplate(object):
    def __init__(self, name, obj):
        self.name = name
        self.obj = obj

    def save(self):
        raise NotImplementedError


import json
class JsonSaver(SaverTemplate):
    def save(self):
        file = open(self.name + '.json', 'wb')
        json.dump(self.object, file)
        file.close()

import cPickle
class PickleSaver(SaverTemplate):
    def save(self):
        file = open(self.name + '.pickle', 'wb')
        cPickle.dump(self.object, file, protocol=cPickle.HIGHEST_PROTOCOL)
        file.close()

import yaml
class PickleSaver(SaverTemplate):
    def save(self):
        file = open(self.name + '.yaml', 'wb')
        yaml.dump(self.object, file)
        file.close()


saver = PickleSaver('whatever', foo)
saver.save()
...