在python应用程序中混合和匹配组件的最佳方法

我有一个组件,它使用我作为消息队列编写的简单发布/子模块.我想试试像RabbitMQ这样的其他实现.但是,我想使这个后端更改可配置,以便我可以在我的实现和第三方模块之间切换清洁度和测试.

显而易见的答案似乎是:

>阅读配置文件
>创建可修改的设置对象/字典
>修改目标组件以延迟加载指定的实现.

就像是 :

# 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,虽然看起来会变得混乱.好处是我不必修改代码来支持交换组件.

任何其他想法或轶事将不胜感激.

编辑:修复缩进.

最佳答案 我之前做过的一件事是创建一个每个特定实现继承自己的公共类.然后有一个可以轻松遵循的规范,每个实现都可以避免重复他们都共享的某些代码.

这是一个糟糕的例子,但您可以看到如何使saver对象使用指定的任何类,其余代码也不关心.

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()
点赞