Пространство имен пакета представляет собой совокупность различных частей, где каждая часть вносит подпакет в родительский пакет. Части могут находиться в разных местах файловой системы. Во время импорта части пакета Python также может искать в zip-файлах, в сети или в любом другом месте. Пространства имен пакета может или не может напрямую соответствовать объектам в файловой системе, части пакета могут быть виртуальными модулями, которые не имеют конкретного представления.
Пространство имен пакета теперь не используют обычный список путей поиска, который может быть указан атрибутом __path__
. Вместо этого он использует пользовательский итеративный тип, который будет автоматически выполнять новый поиск частей пакета при следующей попытке импорта в этом пакете, если путь их родительского пакета (или sys.path
пакета верхнего уровня) изменится.
В настоящее время Python предоставляет pkgutil.extend_path
для обозначения пространства имен пакета.
Рекомендуемый способ использования:
from pkgutil import extend_path __path__ = extend_path(__path__, __name__)
Каждый дистрибутив должен предоставлять одинаковое содержимое в своем __init__.py
файле, так что extension_path
вызывается независимо от того, какая часть пакета будет импортирована первой. Как следствие, файл пакета __init__.py
практически не может определять какая часть пакета импортируется первой, так как он зависит от порядка фрагментов путей пакета в sys.path
. В качестве специальной функции, extension_path
считывает файлы с именем <packagename>.pkg
, что позволяет объявлять дополнительные части пакета.
setuptools
предоставляет аналогичную функцию с именем pkg_resources.declare_namespace
, которая используется в форме:
import pkg_resources pkg_resources.declare_namespace(__name__)
В файле __init__.py
пакета нет необходимости указании __path__
, так как declare_namespace
изменяет переменную пакета __path__
через sys.modules
. Специальная функция, declare_namespace
также поддерживает zip-файлы и регистрирует имя пакета внутри.
setuptools
позволяет объявлять пространство имен пакета в дистрибутиве setup.py
, так что разработчикам дистрибутива не нужно помещать магическую переменную __path__
в файл пакета __init__.py
.