Вопрос о дизайне плагина

1

Моя программа разбита на две части: двигатель, который имеет дело с пользовательским интерфейсом и другими материалами "основной программы", и набор плагинов, которые предоставляют методы для обработки конкретного ввода.

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

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

Я поместил все плагины в подпапку, написал __ init__.py который импортирует каждый плагин, а затем я импортирую папку (я думаю, что это называется пакетом?)

В любом случае, в настоящее время я прямо указываю, что импортировать (что в основном "импортировать это", "импортировать"). Есть ли способ написать мне так, чтобы он импортировал все в этой папке, которая является подключаемым модулем, чтобы я мог добавлять дополнительные плагины без необходимости редактировать файл инициализации?

Теги:

2 ответа

2
Лучший ответ

Вот код, который я использую для этого:

def _loadPackagePlugins(package):
  "Load plugins from a specified package."
  ppath = package.__path__
  pname = package.__name__ + "."
  for importer, modname, ispkg in pkgutil.iter_modules(ppath, pname):
    module = __import__(modname, fromlist = "dummy")

Главное отличие от ответа Якоба заключается в том, что он использует pkgutil.iter_modules вместо os.listdir. Раньше я использовал os.listdir и менялся так, но не помню, почему. Возможно, что os.listdir не удалось, когда я упаковал свое приложение с py2exe и py2app.

  • 0
    Это будет полезно. Спасибо
  • 0
    Странно, и это странный модуль, но мне нравится ответ.
1

У вас всегда может быть указатель под названием plugins, используйте __import__ для импорта модулей и сохранения их таким образом.

например

plugins = {}
for plugin in os.listdir('plugins'):
    plugin = plugin.split()[0]
    plugins[plugin] = __import__(plugin)

Предполагается, что каждый плагин представляет собой один файл. Лично я бы пошел с чем-то, что выглядит в каждой папке для файла __run__.py, например __init__.py в пакете, это указывает на плагин, этот код будет больше похож на что-то вроде этого

for root, dirs, files in os.walk('.'):
    for dir in dirs:
        if "__run__.py" in os.listdir(os.path.join(root, dir)):
            plugins[dir] = __import__(dir)

Код написан без тестирования. YMMV

  • 0
    Гораздо более гибкий, чем наличие одной папки или жесткое кодирование нескольких имен папок. Хорошая идея.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню