Я пишу програму Python, яка в якості аргументу приймає, наприклад:
$ python myapp.py command1
Я хочу, щоб програма була розширюваною, тобто мати можливість додавати нові модулі, які реалізують нові команди, не змінюючи основне джерело програми. Дерево виглядає приблизно так:
myapp/
__init__.py
commands/
__init__.py
command1.py
command2.py
foo.py
bar.py
Тому я хочу, щоб програма знаходила наявні командні модулі під час виконання та виконувала відповідний.
Python визначає функцію __import__ , яка бере рядок для імені модуля:
__import __ (ім'я, глобалі = Ні, місцеві жителі = Немає, зі списку = (), рівень = 0)
Функція імпортує ім'я модуля, потенційно використовуючи задані глобали та локалі, щоб визначити, як інтерпретувати ім'я в контексті пакета. Список списку дає назви об'єктів або підмодулів, які слід імпортувати з модуля, заданого іменем.
Джерело: https://docs.python.org/3/library/functions.html# import
Тому в даний момент у мене є щось на кшталт:
command = sys.argv[1]
try:
command_module = __import__("myapp.commands.%s" % command, fromlist=["myapp.commands"])
except ImportError:
# Display error message
command_module.run()
Це працює чудово, мені просто цікаво, чи існує ідіоматичніший спосіб досягти того, що ми робимо з цим кодом.
Зауважте, що я спеціально не хочу вступати у використання яєць або пунктів розширення. Це не проект з відкритим кодом, і я не очікую, що там будуть "плагіни". Суть у тому, щоб спростити основний код програми та усунути необхідність його модифікувати кожного разу, коли додається новий командний модуль.
dir(__import__)
. У списку списку має бути список імен, що емулюються "від імпорту імені ...".
importlib
: stackoverflow.com/a/54956419/687896