Я работаю над проектом, основным принципом которого является расширяемость.
Я реализовал систему плагинов, определив метакласс, который регистрирует - с помощью метода класса - имя класса любого плагина, который загружается (каждый тип плагина наследуется от определенного класса, определенного в базовом коде , так как в приложении есть разные типы плагинов). В основном это означает, что разработчик должен будет определить свой класс как
class PieChart(ChartPluginAncestor):
# Duck typing:
# Implement compulsory methods for Plugins
# extending Chart functionality
и основная программа узнает о его присутствии, потому что PieChart
будет включен в список зарегистрированных плагинов, доступных по адресу ChartPluginAncestor.plugins
.
Будучи методом монтирования методом класса, все плагины регистрируются, когда их код класса загружается в память (то есть, даже до того, как объект этого класса будет создан) .
Система работает достаточно хорошо ™ для меня (хотя я всегда открыт для предложений о том, как улучшить архитектуру!), Но теперь мне интересно, как лучше всего управлять файлами плагинов ( т.е. где и как должны храниться файлы, содержащие плагины ).
Пока что я использую - для разработки - пакет, который я назвал "плагинами". Я помещаю все мои * .py файлы, содержащие классы плагинов, в каталог пакета, и я просто выдаю import plugins
в файле main.py, чтобы все плагины были правильно смонтированы.
РЕДАКТИРОВАТЬ: Джефф указал в комментариях, что import plugins
классы, содержащиеся в различных модулях пакетов, не будут легко доступны (я не понимал это, как я был - для целей отладки - импорт каждого класса отдельно с from plugins.myAI import AI
).
Однако эта система хороша только во время разработки и тестирования кода, как:
- Плагины могут поставляться с собственными юнит-тестами, и я не хочу загружать их в память.
- Все плагины в настоящее время загружаются в память, но на самом деле есть некоторые плагины, которые являются альтернативными версиями одной и той же функции, поэтому вам просто нужно знать, что вы можете переключаться между ними, но вы хотите загрузить в память только тот, который вы выбрали на панели конфигурации.
- В какой-то момент мне понадобится двойное расположение для установки плагинов: общесистемное расположение (например, где-то под
/usr/local/bin/
) и пользовательское (например, где-то под /home/<user>/.myprogram/
).
Так что мои вопросы на самом деле - возможно, - три:
- Контейнер для плагинов: Какой самый разумный выбор для моей цели? отдельные файлы? пакеты? простой каталог файлов .py?)
- Распознавать наличие плагинов без необходимости их загрузки (импорта): Что такое умный способ использовать интроспекцию Python для этого?
- Размещение плагинов в двух разных местах: Существует ли стандартный / лучший способ (по крайней мере, для GNU / Linux) сделать это?