Модуль импорта из строковой переменной
Я работаю над документацией (личной) для библиотеки вложенных matplotlib (MPL), которая отличается от предоставленной MPL, заинтересованными пакетами подмодулей. Я пишу Python script, который, я надеюсь, автоматизирует создание документов из будущих выпусков MPL.
Я выбрал заинтересованные подмодули/пакеты и хочу перечислить их основные классы, из которых я создам список и обработаю его с помощью pydoc
Проблема в том, что я не могу найти способ проинструктировать Python загрузить подмодуль из строки. Вот пример того, что я пробовал:
import matplotlib.text as text
x = dir(text)
.
i = __import__('matplotlib.text')
y = dir(i)
.
j = __import__('matplotlib')
z = dir(j)
И вот 3-х сравнение этих списков через pprint:
![enter image description here]()
Я не понимаю, что загрузилось в объект y
- это базовый matplotlib
плюс что-то еще, но ему не хватает информации, которую я хотел, и это основные классы из пакета matplotlib.text
. Это верхняя часть синего цвета на снимке экрана (x
)
Пожалуйста, не предлагайте Sphinx как другой подход.
Ответы
Ответ 1
Функция __import__
может быть немного трудно понять.
Если вы измените
i = __import__('matplotlib.text')
к
i = __import__('matplotlib.text', fromlist=[''])
то i
будет ссылаться на matplotlib.text
.
В Python 2.7 и Python 3.1 или более поздней версии вы можете использовать importlib
:
import importlib
i = importlib.import_module("matplotlib.text")
Некоторые примечания
-
Если вы пытаетесь импортировать что-то из подпапки, например. ./feature/email.py
, код будет выглядеть как importlib.import_module("feature.email")
-
Вы ничего не можете импортировать, если в папке нет файла __init__.py
с файлом, который вы пытаетесь импортировать
Ответ 2
importlib.import_module
- это то, что вы ищете. Возвращает импортированный модуль. (Доступно только для Python> = 2.7 или 3.x):
import importlib
mymodule = importlib.import_module('matplotlib.text')
После этого вы можете получить доступ к чему-либо в модуле, как mymodule.myclass
и т.д.
Ответ 3
потратил некоторое время, пытаясь импортировать модули из списка, и это тот поток, который мне больше всего понравился, но я не понял использование ___import____ -
так вот, как импортировать модуль из строки и получить то же поведение, что и импорт. И попробуйте/за исключением случая с ошибкой.:)
pipmodules = ['pycurl', 'ansible', 'bad_module_no_beer']
for module in pipmodules:
try:
# because we want to import using a variable, do it this way
module_obj = __import__(module)
# create a global object containging our module
globals()[module] = module_obj
except ImportError:
sys.stderr.write("ERROR: missing python module: " + module + "\n")
sys.exit(1)
и да, для python 2.7 > у вас есть другие опции, но для 2.6 <, это работает.
Ответ 4
Я разработал эти 3 полезные функции:
def loadModule(moduleName):
module = None
try:
import sys
del sys.modules[moduleName]
except BaseException as err:
pass
try:
import importlib
module = importlib.import_module(moduleName)
except BaseException as err:
serr = str(err)
print("Error to load the module '" + moduleName + "': " + serr)
return module
def reloadModule(moduleName):
module = loadModule(moduleName)
moduleName, modulePath = str(module).replace("' from '", "||").replace("<module '", '').replace("'>", '').split("||")
if (modulePath.endswith(".pyc")):
import os
os.remove(modulePath)
module = loadModule(moduleName)
return module
def getInstance(moduleName, param1, param2, param3):
module = reloadModule(moduleName)
instance = eval("module." + moduleName + "(param1, param2, param3)")
return instance
И каждый раз, когда я хочу перезагрузить новый экземпляр, мне просто нужно вызвать getInstance() следующим образом:
myInstance = getInstance("MyModule", myParam1, myParam2, myParam3)
Наконец, я могу вызвать все функции внутри нового экземпляра:
myInstance.aFunction()
Единственной особенностью здесь является настройка списка параметров вашего экземпляра.