Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Пакеты Основы языка Python

Мы уже знаем, что в Python код хранится в отдельных файлах, называемых модулями. Но если начать делить код достаточно большого проекта на модули, то довольно быстро может возникнуть желание сгруппировать несколько модулей "по смыслу". Или же мы захотим вынести часть модулей из проекта с целью их использования в других проектах. Для объединения модулей в группы служат пакеты (packages).

Итак, пакет — это директория (далее "каталог") с файлами модулей, имеющая имя в формате "snake_case" и содержащая, помимо прочего, специальный модуль с именем "__init__.py". Именно наличие этого специального файла подсказывает интерпретатору Python, что каталог следует воспринимать именно как пакет.

Простейший пакет

Давайте рассмотрим пример простейшего пакета. Пусть пакет состоит из каталога package и модуля __init__.py внутри этого каталога:

package/
└── __init__.py

Файл __init__.py пусть содержит код:

# file __init__.py
NAME = 'super_package'

Это, хотя и небольшой, но уже полноценный пакет. Его можно импортировать так же, как мы импортировали бы модуль:

import package

print(package.NAME)

Заметьте — мы не импортировали файл __init__.py непосредственно. При первом обращении к пакету Python автоматически импортирует модуль __init__.py в этом пакете. Поэтому, очевидно, нельзя импортировать "просто каталог" — ведь каталог без файла __init__.py не будет полноценным пакетом!

Содержимое пакета

С простым пакетом всё ясно — его можно использовать как модуль. Но давайте уже перейдём к группировке в пакете нескольких модулей! Для этого в пакет положим ещё два модуля:

package/
├── constants.py
├── functions.py
└── __init__.py

Содержимое модуля constants.py:

# file constants.py
PERSON = 'Alice'

Содержимое модуля functions.py:

# file functions.py
def greet(who):
    print('Hello, ' + who + '!')

Когда пакет содержит другие модули, кроме __init__.py, то их можно импортировать по их именам. В главе про модули упоминались два варианта импортирования: квалифицированный импорт и импортирование отдельных определений. Квалифицированный импорт в данном случае будет выглядеть так:

import package.functions
import package.constants

package.functions.greet(package.constants.PERSON)  # => Hello, Alice!

Этот вариант самый понятный: в строчке вызова функции greet сразу видно, откуда пришла функция, а откуда — её аргумент. Но писать имя пакета и имя модуля каждый раз — утомительно! Давайте импортируем саму функцию и аргумент:

from package.functions import greet
from package.constants import PERSON

greet(PERSON)  # => Hello, Alice!

Так строчка вызова функции выглядит гораздо лучше! Но помните, что тому, кто будет читать этот код в дальнейшем, потребуется посмотреть в блок импортов, чтобы узнать, откуда функция и константа появились.

Пакеты и импорты

Импорты в Python бывают двух видов: абсолютные и относительные. Понимание разницы становится особенно важным, когда вы начинаете работать с пакетами.

Абсолютные импорты

Абсолютный импорт выглядит как указание полного пути до модуля, включающего все пакеты и подпакеты (subpackages) — да, любой пакет может содержать не только модули, но и вложенные пакеты! Полные пути гарантируют однозначность: интерпретатору всегда понятно, что и откуда импортируется, и читать такие импорты проще.

Относительные импорты

Относительные импорты выглядят так:

from . import module
from .module import function
from .subpackage.module import CONSTANT

Здесь точка означает текущую директорию для модуля, который и осуществляет импорт. К примеру, импорт из .module означают импорт из модуля, находящегося в той же директории, которая содержит модуль с данным импортом. Звучит сложновато? Так и есть! Авторы языка тоже так считают, поэтому уже сейчас относительные импорты лишены части возможностей, которые были доступны в более ранних версиях языка (да, раньше было ещё сложнее!).

Какие же импорты использовать?

Я придерживаюсь мнения большинства: нужно всегда использовать абсолютные импорты! Даже если вы внутри одного пакета один модуль импортируете в другой. Да, при использовании абсолютных импортов приходится писать чуть больше. Но понятность кода — слишком полезное свойство, чтобы от него отказываться!


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Python-разработчик
Профессия
Разработка веб-приложений на Django
25 мая 10 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»