Что означает `__import __ ('pkg_resources'). Declare_namespace (__ name __)` do?
В некоторых __init__.py
файлах модулей я видел такую единственную строку:
__import__('pkg_resources').declare_namespace(__name__)
Что он делает и почему люди его используют? Предположим, что это связано с динамическим импортом и созданием пространства имен во время выполнения.
Ответы
Ответ 1
Это сводится к двум вещам:
-
__import__
- это функция Python, которая импортирует пакет с использованием строки в качестве имени пакета. Он возвращает новый объект, представляющий импортированный пакет. Таким образом, foo = __import__('bar')
будет импортировать пакет с именем bar
и сохранить ссылку на его объекты в локальной переменной объекта foo
.
-
Из настроек utils pkg_resources ' документация, declare_namespace()
"Объявить [s], что имя имени в виде пунктирной точки является" пространством имен пакет ", чьи пакеты и модули могут быть распределены между несколькими дистрибутивами.
Итак, __import__('pkg_resources').declare_namespace(__name__)
импортирует пакет pkg_resources во временный режим и вызывает функцию declare_namespace
, хранящуюся в этом временном (скорее всего, используется функция __import__
, а не оператор import
), так что нет лишних символ, оставшийся по имени pkg_resources
). Если этот код находился в my_namespace/__init__.py
, то __name__
- my_namespace
, и этот модуль будет включен в пакет пространства имен my_namespace
.
Подробнее см. документацию инструменты настройки.
См. этот вопрос для обсуждения более старого механизма достижения такого же эффекта.
См. PEP 420 для стандартизованного механизма, который обеспечивает аналогичную функциональность, начиная с Python 3.3.
Ответ 2
Это способ объявить так называемые "пакеты пространства имен" в Python.
Что это такое и в чем проблема:
Представьте, что вы распространяете программный продукт, который обладает большой функциональностью, и не все люди хотят все это, поэтому вы разбиваете его на куски и отправляете в качестве дополнительных плагинов.
Вы хотите, чтобы люди могли делать
import your_project.plugins.plugin1
import your_project.plugins.plugin2
...
Что хорошо, если ваша структура каталогов точно такая же, как указано выше, а именно
your_project/
__init__.py
plugins/
__init__.py
plugin1.py
plugin2.py
Но что, если вы отправляете эти два плагина в виде отдельных пакетов python, чтобы они находились в двух разных каталогах? Затем вы можете поместить __import__('pkg_resources').declare_namespace(__name__)
в каждый пакет __init__.py
, чтобы Python знал, что эти пакеты являются частью более крупного пакета пространства имен, в нашем случае это your_project.plugins
.
Дополнительную информацию см. в документации.
Ответ 3
Натан, это описание выглядит неверно: "Итак, __import__('pkg_resources').declare_namespace(__name__)
будет импортировать все символы из пакета pkg_resources
, а затем добавить их в пространство имен, имя которого хранится в __name__
."
declare_namespace
не добавляет символы из пакета pkg_resources
в пространство имен, имя которого хранится в __name__
.
declare_namespace
выполняет следующее: "Объявить этот пакет" packageName является пакетом пространства имен ". Ссылка: http://galaxy.readthedocs.io/en/master/lib/pkg_resources.html#pkg_resources.declare_namespace