Вопрос о дизайне плагина - PullRequest
1 голос
/ 30 июня 2011

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

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 30 июня 2011

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

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.

1 голос
/ 30 июня 2011

У вас всегда может быть файл под названием плагины, используйте __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

...