Моя программа разбита на две части: двигатель, который имеет дело с пользовательским интерфейсом и другими материалами "основной программы", и набор плагинов, которые предоставляют методы для обработки конкретного ввода.
Каждый плагин написан в собственном модуле и предоставляет функцию, которая позволит мне отправлять и извлекать данные в плагин и из него.
Имя этой функции одинаково для всех плагинов, поэтому все, что мне нужно, это определить, какой из них вызывать, а затем плагин будет обрабатывать остальные.
Я поместил все плагины в подпапку, написал __ init__.py
который импортирует каждый плагин, а затем я импортирую папку (я думаю, что это называется пакетом?)
В любом случае, в настоящее время я прямо указываю, что импортировать (что в основном "импортировать это", "импортировать"). Есть ли способ написать мне так, чтобы он импортировал все в этой папке, которая является подключаемым модулем, чтобы я мог добавлять дополнительные плагины без необходимости редактировать файл инициализации?
Вот код, который я использую для этого:
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.
У вас всегда может быть указатель под названием 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