У меня есть приложение, написанное на Python, которое используется довольно технической аудиторией (учеными).
Я ищу хороший способ сделать приложение расширяемым пользователями, то есть архитектуру сценариев / плагинов.
Я ищу что-то чрезвычайно легкое . Большинство сценариев, или плагинов, не будут разрабатываться и распространяться сторонними разработчиками и устанавливаться, но через несколько минут пользователь собирается что-то сделать, чтобы автоматизировать повторяющуюся задачу, добавить поддержку формата файла, и т.д. Таким образом, плагины должны иметь абсолютный минимальный шаблонный код и не требовать «установки», кроме копирования в папку (поэтому что-то вроде точек входа setuptools или архитектуры плагинов Zope выглядит слишком много.)
Существуют ли какие-либо системы, подобные этой, или какие-либо проекты, которые реализуют аналогичную схему, на которую я должен обратить внимание для идей / вдохновения?
imp
Модуль является устаревшим в пользуimportlib
начиная с питоном 3.4imp.load_module
.module_example.py
:loader.py
:Он, безусловно, «минимальный», в нем нет абсолютно никакой проверки ошибок, возможно, множество проблем с безопасностью, он не очень гибкий - но он должен показать вам, насколько простой может быть система плагинов в Python.
Вы , вероятно , хотите , чтобы заглянуть в имп модуль тоже, хотя вы можете сделать много с просто
__import__
,os.listdir
и некоторые строки манипуляции.источник
def call_plugin(name, *args)
кdef call_plugin(name, *args, **kwargs)
, а затемplugin.plugin_main(*args)
вplugin.plugin_main(*args, **kwargs)
imp
устарела в пользуimportlib
Посмотрите на этот обзор существующих платформ / библиотек плагинов , это хорошая отправная точка. Я очень люблю япсы , но это зависит от вашего варианта использования.
источник
Хотя этот вопрос действительно интересный, я думаю, что на него довольно сложно ответить без подробностей. Что это за приложение? У него есть графический интерфейс? Это инструмент командной строки? Набор скриптов? Программа с уникальной точкой входа и т.д ...
Учитывая небольшую информацию, которую я имею, я отвечу в очень общей форме.
Что значит добавить плагины?
На основе чистого кода / практики проектирования вам нужно будет четко определить, какое поведение / конкретные действия вы хотите расширить для своих пользователей. Определите общую точку входа / набор функций, которые всегда будут переопределены, и определите группы в рамках этих действий. Как только это будет сделано, ваше приложение должно легко расширяться,
Пример использования хуков , вдохновленных MediaWiki (PHP, но действительно ли язык имеет значение?):
Еще один пример, вдохновленный ртутью. Здесь расширения только добавляют команды к исполняемый файл командной строки hg , расширяя поведение.
Для обоих подходов вам может понадобиться общий инициализация и финализация вашего расширения. Вы можете либо использовать общий интерфейс, который нужно реализовать всем вашим расширением (лучше подходит для второго подхода; Mercurial использует reposetup (ui, repo), который вызывается для всех расширений), либо использовать подход типа ловушки с hooks.setup hook.
Но опять же, если вы хотите получить более полезные ответы, вам придется сузить свой вопрос;)
источник
Простая структура плагинов Марти Аллчина - это база, которую я использую для своих нужд. Я действительно рекомендую взглянуть на это, я думаю, что это действительно хорошее начало, если вы хотите что-то простое и легко взломанное. Вы также можете найти его как Django Snippets .
источник
Я биолог в отставке, который занимался цифровыми микрографами и обнаружил, что ему нужно написать пакет обработки и анализа изображений (технически это не библиотека) для работы на машине SGi. Я написал код на C и использовал Tcl для языка сценариев. GUI, каким бы он ни был, был сделан с использованием Tk. Команды, которые появились в Tcl, имели форму «extensionName commandName arg0 arg1 ... param0 param1 ...», то есть простые разделенные пробелом слова и числа. Когда Tcl увидел подстроку extensionName, управление было передано пакету C. Это, в свою очередь, запускало команду через лексер / парсер (сделанный в lex / yacc) и затем вызывало подпрограммы Си по мере необходимости.
Команды для работы с пакетом можно запускать одну за другой через окно в графическом интерфейсе, но пакетные задания выполнялись путем редактирования текстовых файлов, которые были действительными сценариями Tcl; Вы выбрали шаблон, который выполнял ту операцию на уровне файлов, которую вы хотели выполнить, и затем отредактировали копию, чтобы она содержала действительные имена каталогов и файлов, а также команды пакета. Оно работало завораживающе. До того как ...
1) Мир превратился в ПК и 2) сценарии получили более 500 строк, когда неудобные организационные возможности Tcl начали становиться настоящим неудобством. Время прошло ...
Я вышел на пенсию, Python был изобретен, и это выглядело как идеальный преемник Tcl. Теперь я никогда не занимался портом, потому что никогда не сталкивался с проблемами компиляции (довольно больших) программ на C на ПК, расширения Python с помощью пакета C и создания GUI на Python / Gt? / Tk? /? ?. Тем не менее, старая идея наличия редактируемых шаблонных скриптов кажется все еще работоспособной. Кроме того, ввод команд пакета в нативной форме Python не должен быть слишком тяжелым, например:
packageName.command (arg0, arg1, ..., param0, param1, ...)
Несколько лишних точек, паренов и запятых, но это не шоу-стопперы.
Я помню, что кто-то делал версии lex и yacc на Python (попробуйте: http://www.dabeaz.com/ply/ ), поэтому, если они все еще нужны, они есть.
Суть этого бессвязного в том, что мне показалось, что сам Python - это желаемый «легкий» интерфейс, используемый учеными. Мне любопытно узнать, почему вы думаете, что это не так, и я имею в виду это серьезно.
добавлено позже: Gedit приложения ожидает добавления плагинов, и на их сайте есть самое ясное объяснение простой процедуры плагинов, которую я нашел за несколько минут осмотра. Пытаться:
https://wiki.gnome.org/Apps/Gedit/PythonPluginHowToOld
Я все еще хотел бы лучше понять ваш вопрос. Мне неясно, хотите ли вы, 1), чтобы ученые могли использовать ваше (Python) приложение довольно просто различными способами, или 2) хотите, чтобы ученые добавили новые возможности в ваше приложение. Выбор № 1 - это ситуация, с которой мы столкнулись с изображениями, и которая заставила нас использовать общие сценарии, которые мы изменили в соответствии с потребностями момента. Это вариант № 2, который приводит вас к идее плагинов, или это какой-то аспект вашего приложения, который делает невыполнимым выполнение команд?
источник
Когда я искал Python Decorators, нашел простой, но полезный фрагмент кода. Это может не соответствовать вашим потребностям, но очень вдохновляет.
Scipy Advanced Python # Система регистрации плагинов
Использование:
источник
WordProcessor.plugin
ничего не возвращается (None
), поэтому, импортируяCleanMdashesExtension
класс позже, вы просто импортируетеNone
. Если классы плагинов полезны сами по себе, создайте.plugin
метод classreturn plugin
.Мне понравилось приятное обсуждение различных архитектур плагинов, которое д-р Андре Роберге дал на Pycon 2009. Он дает хороший обзор различных способов реализации плагинов, начиная с чего-то действительно простого.
Это доступно как подкаст (вторая часть после объяснения исправления обезьяны), сопровождаемый серией шести записей в блоге .
Я рекомендую внимательно выслушать его, прежде чем принять решение.
источник
Я приехал сюда в поисках минимальной архитектуры плагинов и обнаружил много вещей, которые мне показались излишними. Итак, я реализовал Super Simple Python Plugins . Чтобы использовать его, вы создаете один или несколько каталогов и добавляете специальный
__init__.py
файл в каждый. Импортирование этих каталогов приведет к загрузке всех других файлов Python в виде подмодулей, и их имена будут помещены в__all__
список. Затем вы должны проверить / инициализировать / зарегистрировать эти модули. В файле README есть пример.источник
На самом деле setuptools работает с «каталогом плагинов», как показано в следующем примере из документации проекта: http://peak.telecommunity.com/DevCenter/PkgResources#locating-plugins
Пример использования:
В долгосрочной перспективе setuptools является гораздо более безопасным выбором, поскольку он может загружать плагины без конфликтов или отсутствующих требований.
Еще одним преимуществом является то, что сами плагины могут быть расширены с использованием того же механизма, без необходимости в исходных приложениях.
источник
В качестве одного из подходов к системе плагинов, Вы можете проверить проект «Расширяй меня» .
Например, давайте определим простой класс и его расширение
И попробуйте использовать это:
И покажи, что скрыто за кулисами:
Библиотека extend_me управляет процессом создания класса с помощью метаклассов, таким образом, в примере выше, при создании нового экземпляра
MyCoolClass
мы получили экземпляр нового класса, который является подклассом обоихMyCoolClassExtension
иMyCoolClass
обладает функциональностью обоих из них, благодаря множественному наследованию PythonДля лучшего контроля над созданием классов в этой библиотеке есть несколько метаклассов:
ExtensibleType
- допускает простую расширяемость путем создания подклассовExtensibleByHashType
- похож на ExtensibleType, но имеет возможность создавать специализированные версии класса, позволяя глобальное расширение базового класса и расширение специализированных версий классаЭта библиотека используется в проекте OpenERP Proxy и, кажется, работает достаточно хорошо!
Для реального примера использования посмотрите в расширении 'field_datetime' OpenERP Proxy :
Record
вот расширяемый объект.RecordDateTime
это расширение.Чтобы включить расширение, просто импортируйте модуль, который содержит класс расширения, и (в случае выше) все
Record
объекты, созданные после него, будут иметь класс расширения в базовых классах, таким образом, имея всю свою функциональность.Основным преимуществом этой библиотеки является то, что код, который управляет расширяемыми объектами, не должен знать о расширении, и расширения могут изменить все в расширяемых объектах.
источник
my_cool_obj = MyCoolClassExtension1()
вместоmy_cool_obj = MyCoolClass()
__new__
метод, поэтому он автоматически находит все подклассы и создает новый класс, который является подклассом для всех них, и возвращает новый экземпляр этого созданного класса. Таким образом, оригинальному приложению не нужно знать обо всех расширениях. этот подход полезен при создании библиотеки, чтобы позволить конечному пользователю легко изменять или расширять его поведение. в приведенном выше примере MyCoolClass может быть определен в библиотеке и использован ею, а MyCoolClassExtension может быть определен конечным пользователем.У setuptools есть EntryPoint :
AFAIK этот пакет всегда доступен, если вы используете pip или virtualenv.
источник
В качестве дополнения к ответу @ edomaur, я могу предложить взглянуть на simple_plugins (бесстыдный плагин), который представляет собой простую структуру плагинов, вдохновленную работой Марти Алчина .
Краткий пример использования на основе README проекта:
источник
Я потратил время на чтение этой ветки, пока искал фреймворк для плагинов в Python. Я использовал некоторые, но были недостатки с ними. Вот что я придумываю для вашего исследования в 2017 году, свободной от интерфейса, слабо связанной системы управления плагинами: загрузите меня позже . Вот учебники о том, как его использовать.
источник
Вы можете использовать pluginlib .
Плагины просты в создании и могут быть загружены из других пакетов, путей к файлам или точек входа.
Создайте родительский класс плагина, определяя любые необходимые методы:
Создайте плагин, унаследовав родительский класс:
Загрузите плагины:
источник
foo
вас может быть модуль, вfoo.parents
котором вы определяете родительские классы. Тогда ваши плагины будут импортированыfoo.parents
. Это хорошо работает для большинства случаев использования. Поскольку «foo» также импортируется, чтобы избежать возможности циклического импорта, многие проекты оставляют корень модуля пустым и используют__main__.py
файл или точки входа для запуска приложения.Я потратил много времени, пытаясь найти небольшую систему плагинов для Python, которая бы соответствовала моим потребностям. Но тогда я просто подумал, что если наследство уже есть, которое является естественным и гибким, почему бы не использовать его.
Единственная проблема с использованием наследования для плагинов состоит в том, что вы не знаете, какие классы плагинов наиболее специфичны (самые низкие в дереве наследования).
Но это можно решить с помощью метакласса, который отслеживает наследование базового класса, и, возможно, может создать класс, который наследуется от большинства конкретных плагинов («Root extended» на рисунке ниже)
Итак, я пришел с решением, написав такой метакласс:
Поэтому, когда у вас есть Root-база, созданная с метаклассом, и у вас есть дерево плагинов, которые наследуют его, вы можете автоматически получить класс, который наследует от самых специфических плагинов, просто создав подклассы:
Кодовая база довольно мала (~ 30 строк чистого кода) и настолько гибка, насколько позволяет наследование.
Если вам интересно, присоединяйтесь @ https://github.com/thodnev/pluginlib
источник
Вы также можете взглянуть на Groundwork .
Идея состоит в том, чтобы создавать приложения вокруг повторно используемых компонентов, называемых шаблонами и плагинами. Плагины - это классы, которые являются производными от
GwBasePattern
. Вот основной пример:Есть также более продвинутые шаблоны для обработки, например, интерфейсов командной строки, сигнализации или общих объектов.
Groundwork находит свои плагины либо программно, связывая их с приложением, как показано выше, либо автоматически через
setuptools
. Пакеты Python, содержащие плагины, должны объявлять их с помощью специальной точки входаgroundwork.plugin
.Вот документы .
Отказ от ответственности : я один из авторов Groundwork.
источник
В нашем текущем медицинском продукте у нас есть подключаемая архитектура с интерфейсом класса. Наш технический стек - это Django поверх Python для API и Nuxtjs поверх nodejs для внешнего интерфейса.
Для нашего продукта написано приложение менеджера плагинов, которое в основном состоит из пакетов pip и npm в соответствии с Django и Nuxtjs.
Для разработки нового плагина (pip и npm) мы сделали менеджер плагинов в качестве зависимости.
В пакете Pip: с помощью setup.py вы можете добавить точку входа плагина, чтобы что-то делать с менеджером плагинов (реестр, инициации, ... и т. Д.) Https://setuptools.readthedocs.io/en/latest/setuptools .html # автоматического сценария создания
В пакете npm: Как и в pip, в скриптах npm есть хуки для установки. https://docs.npmjs.com/misc/scripts
Наш случай использования:
Команда разработчиков плагинов теперь отделена от основной команды разработчиков. Сфера разработки плагинов предназначена для интеграции со сторонними приложениями, которые определены в любой из категорий продукта. Интерфейсы плагинов подразделяются, например, на: - Факс, телефон, электронная почта ... и т. Д. Менеджер плагинов может быть расширен до новых категорий.
В вашем случае: может быть, вы можете написать один плагин и повторно использовать его для других вещей.
Если разработчикам плагинов необходимо использовать повторно использовать основные объекты, этот объект можно использовать, выполнив уровень абстракции в менеджере плагинов, чтобы любые плагины могли наследовать эти методы.
Просто поделитесь, как мы внедрили в наш продукт, надеюсь, что это даст немного идеи.
источник