Как реализовать реализацию объектов времени выполнения (разных) с использованием Python

Мое требование состоит в том, чтобы у меня была стандартная структура генерации HTML в PDF в 3 этапа:

1) Получите информацию из нашей БД и создайте из нее смысл, прочитайте XML и переопределите или определили настройки и т. Д. - pre_processing

2) Создание шаблона HTML с использованием предварительно обработанных данных - render_template

3) Запустите конвертированный HTML в PDF и получите PDF обратно. - invoke_service

Теперь возможно, что иногда понадобятся разные механизмы PDF, и реализации могут измениться... Возможно даже, что для некоторых из них требуются очень строгие данные или собственные настройки

Поэтому мне может понадобиться расширить 1, перегрузку 2, перегрузку 3, и я хотел бы сделать эту реализацию настраиваемой и легко переключаемой.

Я думаю о создании базового класса, а затем о создании реализации Foo.py и реализации Bar.py, которые фактически будут объектами времени выполнения. Как я могу получить это с простым Python?

Ужасный способ, которым я могу думать, является:

#Module Name ServiceHandler

def implementation(imp_name):
    try:
       from imp_name import imp_class
       return imp_class(AbtractClass) 
    else:
       Sorry No Implemenation Found!

class AbstractClass(...)
      def __init__



Gets invoked in another object method as 


self.ServiceHandler.implementation(read_from_xml)

Кто-нибудь может дать мне хорошие советы, чтобы решить эту проблему? По сути, я хочу Foo(Base) или Bar(Base), и это должно быть похоже на чтение конфигурации и сопоставление ее с этим.

Мой текущий макет модуля:

module.py

  • base.py
  • foo.py
  • bar.py
  • unknown.py должен быть легко расширяемым.

1 ответ

Решение

Я бы сделал что-то подобное:

# file : service_handler.py
from importlib import import_module

# get parameters from your config file beforehand
def get_backend(backend_name, **kwargs): 

    # example : foo.Spam gets backend Spam from module foo
    backend_module, backend_class = backend_name.rsplit('.', 1)

    mdl = import_module(backend_module)
    cls = getattr(mdl, backend_class) 

    return cls(**kwargs) # create the object

Определите ваши бэкэнды, как вы хотите (используя абстрактные классы или вводить утки).

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

Такие проекты, как django, делают много вещей с множеством бэкэндов, дают возможность взглянуть на их кодовую базу.

Другие вопросы по тегам