Импортировать файл, используя строку как имя
Возможный дубликат:
Импорт динамического модуля в Python
Я собираюсь сделать набор файлов в какой-то момент в ближайшее время, и лучший способ организовать его - иметь список, этот список будет в самом верху файла, а после него будет смешное количество код для обработки того, что этот список контролирует и как он работает. Я хочу написать указанный список только один раз, и указанный список - это список имен папок и файлов в этом формате:
[(folder/filename, bool, bool, int), (folder/filename, bool, bool, int)]
Как вы можете видеть, folder/filename
являются одинаковыми (вроде). Имя файла - это имя папки с .py
в конце, но при импорте XXX вам не нужно импортировать XXX.py, поэтому я не вижу, чтобы это вызывало проблему.
Проблема, с которой я сталкиваюсь, импортируется с помощью этого метода...
for (testName, auto, hardware, bit) in testList:
print(testName)
paths = "\\" + testName
print paths
addpath(paths)
sys.modules[testName] = testName # One of a few options I've seen suggested on the net
print("Path Added")
test = testName + ".Helloworld()"
eval(test)
Итак, для каждого теста у меня есть, напечатайте имя, соберите строку, содержащую путь ("\\testName"
), в этом примере напечатайте тестовый путь, затем добавьте путь к списку (sys.path.append(path)
), затем распечатать, чтобы подтвердить, что это произошло, а затем собрать строку, которая будет выполняться eval
для основного модуля тестов и в конечном итоге оценить его.
Как вы можете видеть, в настоящее время мне нужно иметь список импорта вверху. Я не могу просто импортировать testName
(содержимое testName
- это имя модуля, который я хочу импортировать), поскольку он попытается найти модуль под названием testName
, а не модуль, называемый содержимым testName
.
Я видел несколько примеров того, где это было сделано, но не может найти того, что работает в моих обстоятельствах. Если кто-то может буквально бросить кусок кода, который сделает это, было бы замечательно.
Я также просил бы, чтобы я не был висел, ни рисован, ни расквартирован для использования eval, он используется в очень контролируемой среде (список, через который он циклически входит в файл .py, поэтому no "end пользователь" должен возиться с ним).
Ответы
Ответ 1
Не уверен, правильно ли я все понял, но вы можете импортировать модуль динамически с помощью __import__
:
mod = __import__(testName)
mod.HelloWorld()
Изменить: я не знал, что использование __import__
было обескуражено документами python для кода пользователя: Документация __import__ (как отметил Бакуриу)
Это также должно работать и будет считаться лучшим стилем:
import importlib
mod = importlib.import_module(testName)
mod.HelloWorld()
Ответ 2
- Никогда, никогда, никогда не связывайтесь с
sys.modules
напрямую, если вы точно не знаете, что делаете.
- Существует множество способов сделать то, что вы хотите:
Я бы не использовал __import__
напрямую и перешел на importlib.import_module
(что также предлагается в конце документации __import__
).
Ответ 3
Добавьте путь, по которому модуль находится в sys.path. Импортируйте модуль с помощью функции __import__, которая принимает строчную переменную в качестве имени модуля.
import sys
sys.path.insert(0, mypath) # mypath = path of module to be imported
imported_module = __import__("string_module_name") # __import__ accepts string
imported_module.myfunction() # All symbols in mymodule are now available normally