Importing module from string variable using "__import__" gives different results than a normal import statement
Импорт модуля из строковой переменной с использованием "__import__" дает результаты, отличные от обычной инструкции импорта
Я работаю над документацией (личной) для вложенной библиотеки matplotlib (MPL), которая отличается от предоставленной самой MPL, заинтересованными пакетами подмодулей. Я пишу скрипт на Python, который, я надеюсь, автоматизирует генерацию документов из будущих выпусков 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:
Я не понимаю, что загружено в y object - это base matplotlib плюс что-то еще, но в нем отсутствует информация, которую я хотел, и это основные классы из matplotlib.text пакета. Это верхняя часть синего цвета на скриншоте (x список).
Переведено автоматически
Ответ 1
Функция __import__ может быть немного сложной для понимания.
Если вы измените
i = __import__('matplotlib.text')
Для
i = __import__('matplotlib.text', fromlist=[''])
затем i будет ссылаться на matplotlib.text.
В Python 3.1 или более поздней версии вы можете использовать importlib:
import importlib
i = importlib.import_module("matplotlib.text")
Some notes
If you're trying to import something from a sub-folder e.g. ./feature/email.py, the code will look like importlib.import_module("feature.email")
Before Python 3.3 you could not import anything if there was no __init__.py in the folder with file you were trying to import (see caveats before deciding if you want to keep the file for backward compatibility e.g. with pytest).
# equiv. of your `import matplotlib.text as text` text = importlib.import_module('matplotlib.text')
You can thereafter access anything in the module as text.myclass, text.myfunction, etc.
Ответ 3
spent some time trying to import modules from a list, and this is the thread that got me most of the way there - but I didnt grasp the use of ___import____ -
so here's how to import a module from a string, and get the same behavior as just import. And try/except the error case, too. :)
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)
and yes, for python 2.7> you have other options - but for 2.6<, this works.
Ответ 4
Apart from using the importlib one can also use exec method to import a module from a string variable.
Here I am showing an example of importing the combinations method from itertools package using the exec method:
MODULES = [ ['itertools','combinations'], ]
for ITEM in MODULES: import_str = "from {0} import {1}".format(ITEM[0],', '.join(str(i) for i in ITEM[1:])) exec(import_str)
ar = list(combinations([1, 2, 3, 4], 2)) for elements in ar: print(elements)