Как я могу импортировать пакет с помощью __import __ (), если имя пакета известно только во время выполнения? - PullRequest
15 голосов
/ 29 июня 2009

У меня есть папка сообщений (пакет) с файлом __init__.py и другим модулем messages_en.py внутри. В __init__.py, если я импортирую messages_en, это работает, но __import__ завершается с ошибкой «ImportError: Нет модуля с именем messages_en»

import messages_en # it works
messages = __import__('messages_en') # it doesn't ?

Раньше я думал, что «import x» - это просто еще один способ сказать __import__('x')

Ответы [ 7 ]

19 голосов
/ 29 июня 2009

Если это проблема пути, вы должны использовать аргумент level (из документов ):

__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module

Level is used to determine whether to perform
absolute or relative imports.  -1 is the original strategy of attempting
both absolute and relative imports, 0 is absolute, a positive number
is the number of parent directories to search relative to the current module.
18 голосов
/ 01 ноября 2012

Для меня достаточно добавить аргумент globals:

__import__('messages_en', globals=globals())

На самом деле здесь требуется только __name__:

__import__('messages_en', globals={"__name__": __name__})
14 голосов
/ 29 июня 2009

__import__ является внутренней функцией, вызываемой оператором импорта. В повседневном кодировании вам не нужно (или не хочется) звонить __import__

из документации по питону:

Например, оператор import spam приводит к байт-коду, напоминающему следующий код:

spam = __import__('spam', globals(), locals(), [], -1)

С другой стороны, оператор from spam.ham import eggs, sausage as saus приводит к

_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1)
eggs = _temp.eggs
saus = _temp.sausage

больше информации: http://docs.python.org/library/functions.html

3 голосов
/ 10 мая 2010

Обязательно добавьте каталог модулей к вашему пути Python.

Ваш путь (список каталогов, которые Python просматривает для поиска модулей и файлов) хранится в атрибуте пути модуля sys. Поскольку путь является списком, вы можете использовать метод append для добавления новых каталогов в путь.

Например, чтобы добавить каталог / home / me / mypy в путь:

import sys
sys.path.append("/home/me/mypy") 
0 голосов
/ 15 марта 2019

Я понимаю, что этот вопрос касается функции __import__(), но я думаю, что пакет importlib лучше всего подходит для импорта пакетов во время выполнения, если вы используете Python 2.7 или выше, как рекомендовано в doc * 1004.*:

Примечание: Программный импорт модулей должен использовать import_module () вместо этой функции.

Возможные ошибки: Это было введено в python 2.7:

Новое в версии 2.7.

Этот модуль является второстепеннымподмножество того, что доступно в более полнофункциональном пакете с тем же именем из Python 3.1, который обеспечивает полную реализацию импорта.Что здесь предоставлено, чтобы облегчить переход с 2.7 на 3.1.

В вашем случае вы можете использовать:

import importlib

messages = importlib.import_module('messages_en')

Кроме того, если вы хотите указатьимя пакета, тогда from messages import messages_en может быть записано как:

importlib.import_module('.messages_en', 'messages')

Обратите внимание на . в .messages_en, используемом для относительного разрешения пути, как описано здесь :

... Аргумент name указывает, какой модуль импортировать в абсолютном или относительном выражении (например, pkg.mod или ..mod).Если имя указано в относительных терминах, то аргумент пакета должен быть установлен на имя пакета, которое должно выступать в качестве якоря для разрешения имени пакета (например, import_module ('.. mod', 'pkg.subpkg')будет импортировать pkg.mod).

0 голосов
/ 09 июня 2015

Вам необходимо вручную импортировать верхний пакет вашего динамического пути пакета.

Например, в начале файла я пишу:

import sites

потом в коде это работает для меня:

target = 'some.dynamic.path'
my_module = __import__ ('sites.%s.fabfile' % target, fromlist=["sites.%s" % target])
0 голосов
/ 29 июня 2009

Вы можете попробовать это:

messages == __import__('Foo.messages_en', fromlist=['messages_en'])
...