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