Как предоставить API для расширения программы на Python с помощью плагинов? - PullRequest
5 голосов
/ 04 июля 2011

Мне было интересно, как я могу предоставить API для моей программы на Python, чтобы другие могли расширять ее с помощью плагинов. Я думал о чем-то вроде from myProgram.plugins import aClassToExtendByOthers, registerThatClass. Но я понятия не имею, как это обеспечить.

Я мог бы использовать выражение exec в моей функции loadPlugins для каждого плагина в папке плагинов, но это не позволило бы импортировать то, что я хотел бы предоставьте людям возможность писать эти плагины.

Ответы [ 2 ]

2 голосов
/ 04 июля 2011

Для системы, которую я использую в нескольких своих программах, я определяю каталог плагинов и предоставляю базовый класс плагинов для всех плагинов для подкласса.Затем я импортирую все модули в каталоге и выборочно инициализирую (проверяя, не являются ли они подклассами моего базового класса плагинов), и храню экземпляры плагинов в словаре (или списке).Я обнаружил, что шаблон отправки команд эффективно работал для меня как способ структурирования плагинов и передачи событий.Базовый плагин (или другой необязательный интерфейсный класс) может предоставлять методы, необходимые плагину для взаимодействия с приложением.Надеюсь, это поможет.Возможно, это не лучший способ сделать это, но это сработало для меня.

Кроме того, вы можете выполнить дополнительную фильтрацию, например, требовать, чтобы файлы плагинов имели префикс (например, __plug_file.py__ и __plug_other.py__).

0 голосов
/ 07 июля 2011

вы можете использовать модуль imp (см. Docs.python.org)

sys.path.insert(0, pluginsDir)
lst = map(lambda x: os.path.splitext(os.path.basename(x))[0], glob.glob(os.path.join(pluginsDir, "*.py")))
for module in lst:
try:
  f, fn, d = imp.find_module(module,[pluginsDir])
  loaded = imp.load_module(module, f, fn, d)

, для полнофункционального примера см. Загрузчик центра управления ojuba

http://git.ojuba.org/cgit/occ/tree/OjubaControlCenter/loader.py

...