Что делает `__import __ ('pkg_resources'). Declare_namespace (__ name __)`? - PullRequest
48 голосов
/ 16 октября 2011

В некоторых __init__.py файлах модулей я видел такую ​​единственную строку:

__import__('pkg_resources').declare_namespace(__name__)

Что он делает и почему люди его используют?Предположим, это связано с динамическим импортом и созданием пространства имен во время выполнения.

Ответы [ 2 ]

39 голосов
/ 17 октября 2011

Это сводится к двум вещам:

  1. __import__ - это функция Python, которая будет импортировать пакет, используя строку в качестве имени пакета.Возвращает новый объект, который представляет импортированный пакет.Поэтому foo = __import__('bar') импортирует пакет с именем bar и сохранит ссылку на его объекты в локальной переменной объекта foo.

  2. Из установочных утилит pkg_resources ' документация, declare_namespace() "Объявите [s], что пунктирное имя пакета name является" пакетом пространства имен ", чьи содержащиеся в нем пакеты и модули могут быть распределены по нескольким дистрибутивам."

Таким образом, __import__('pkg_resources').declare_namespace(__name__) импортирует пакет 'pkg_resources' во временный и вызовет функцию declare_namespace, хранящуюся в этом временном хранилище (скорее всего, используется функция __import__, а не оператор import, так что нетлишний символ остался над именем pkg_resources).Если этот код был в my_namespace/__init__.py, тогда __name__ равен my_namespace, и этот модуль будет включен в пакет пространства имен my_namespace.

См. Документацию setup tools для получения дополнительной информации.детали

См. этот вопрос для обсуждения более старого механизма достижения того же эффекта.

См. PEP 420 для стандартизированного механизма, который обеспечивает аналогичныйфункциональность начиная с Python 3.3.

7 голосов
/ 09 мая 2016

Это способ объявить так называемые «пакеты пространства имен» в 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.

Пожалуйста, обратитесь к документации для получения дополнительной информации.

...