Пакеты могут содержать вложенные пакеты произвольной глубины. Имена вложенных пакетов отделены от имени родительского пакета точками, похожими на стандартный синтаксис доступа к атрибутам Python. Таким образом, у вас может быть модуль с именем md и пакет pkg, который, в свою очередь, имеет подпакет pkg.sub_pkg1 и модуль внутри этого подпакета pkg.sub_pkg1.mod2.
Для примера создадим такую иерархию каталогов и модулей:
-- pkg
|
|-- sub_pkg1
| |-- mod1.py
| |-- mod2.py
|
|
|-- sub_pkg2
|-- mod3.py
|-- mod4.py
Модули будут содержать следующий код:
mod1.py:
def one(): print('Модуль 1, функция one()')
mod2.py:
def two(): print('Модуль 2, функция two()')
mod3.py:
def three(): print('Модуль 3, функция three()')
mod4.py:
def four(): print('Модуль 4, функция four()')
Импорт работает так же, но для отделения имени пакета от имени вложенного пакета используется дополнительная точечная нотация:
>>> import pkg.sub_pkg1.mod1 >>> pkg.sub_pkg1.mod1.one() # Модуль 1, функция one() >>> from pkg.sub_pkg1 import mod2 >>> mod2.two() # Модуль 2, функция two() >>> from pkg.sub_pkg2.mod3 import three >>> three() # Модуль 3, функция three() >>> from pkg.sub_pkg2.mod4 import four as baz >>> baz() # Модуль 4, функция four()
Модуль в одном вложенном пакете может ссылаться на объекты в любом дочернем вложенном пакете. В примере ниже, выполним функцию one(), определенную в модуле mod1 из модуля mod3. Для этого изменим файл модуля mod3.py, будем использовать абсолютный импорт модуля mod1:
pkg/sub__pkg2/mod3.py:
def three(): print('Модуль 3, функция three()') from pkg.sub_pkg1.mod1 import one one()
Теперь в консоли Python импортируем модуль mod3 из вложенного пакета sub_pkg2:
>>> from pkg.sub_pkg2 import mod3 # Модуль 1, функция one() >>> mod3.one() # Модуль 1, функция one()
Для импорта вложенных пакетов можно использовать относительный импорт. Одна начальная точка указывает на относительный импорт, начиная с текущего пакета. Две или более передних точек указывают на относительный импорт в родительский пакет(ы) текущего пакета, один уровень на точку после первого.
В примере ниже from .. вычисляет родительский пакет pkg, а from ..sub_pkg1 вычисляется как вложенный пакет sub_pkg1 родительского пакета.
pkg/sub__pkg2/mod3.py:
def three(): print('Модуль 3, функция three()') from .. import sub_pkg1 print(sub_pkg1) from ..sub_pkg1.mod1 import one
>>> from pkg.sub_pkg2 import mod3 # <module 'pkg.sub_pkg1' (namespace)> >>> mod3.one() # Модуль 1, функция one()
Обратите внимание, что при использовании импорта из пакета конструкции вида from pkg.sub_pkg2.mod3 import three элемент может быть либо подмодулем (или подпакетом) пакета, либо каким-либо другим именем, определенным в пакете, например функцией, классом или переменной. Оператор import сначала проверяет, определен ли элемент в пакете, если нет, он предполагает, что это модуль, и пытается загрузить его. Если он не находит его, то возникает исключение ImportError.
И наоборот, при использовании синтаксиса типа import pkg.sub_pkg2.mod3 каждый элемент, кроме последнего, должен быть пакетом или вложенным пакетом. Последний элемент точечной нотации может быть модулем или пакетом, но не может быть классом, функцией или переменной, определенной в предыдущем элементе.