Основы Python
Теория: Пакеты
Обычно код в больших проектах делят на модули — отдельные файлы, в которых хранится код на Python. Но иногда и этого разделения недостаточно. Часто модули хочется сгруппировать «по смыслу» или сформировать отдельную группу модулей, чтобы использовать их в других проектах.
В таких случаях помогают пакеты — группы модулей. В особенно больших проектах используются еще и подпакеты внутри пакетов, но на этой теме мы пока не будем останавливаться. В этом уроке разберемся, как создавать пакеты и добавлять в них модули. Также поговорим о том, какими способами можно импортировать пакеты в проект.
Создаем пакет
С точки зрения структуры пакет — это директория с файлами модулей, с названием в формате snake_case и содержащая специальный модуль с именем __init__.py. Именно наличие этого специального файла подсказывает интерпретатору Python, что директорию следует воспринимать как пакет.
Рассмотрим пример самого простого пакета. Создадим пакет из директории package и модуля __init__.py:
В файл __init__.py добавим следующий код:
Теперь у нас есть небольшой, но уже полноценный пакет. Его можно импортировать так же как модуль:
Обратите внимание, что отдельно импортировать файл __init__.py не нужно. При первом обращении к пакету Python самостоятельно импортирует модуль __init__.py. Это происходит автоматически, потому что директория без init-файла не будет считаться пакетом.
Добавляем модули в пакет
С простым пакетом все ясно — его можно использовать как модуль. Теперь перейдем к группировке. Добавим в пакет еще два модуля:
Чтобы было понятнее, рассмотрим содержимое модуля constants.py:
И содержимое модуля functions.py:
Теперь в пакете есть не только __init__.py, но и еще два модуля — теперь их можно импортировать.
Как импортировать модули из пакетов
Импорт модулей из пакета выглядит так же, но к имени модуля приписывается имя пакета. То есть указывается путь до модуля.
Например, импорт всего модуля выглядит так:
К названию модуля functions приставляется название пакета package, где этот модуль и лежит. Обратите внимание, что путь указывается через точку.
Попробуем импортировать отдельные определения, то есть саму функцию и аргумент:
При импорте модуля из пакета всегда важно указывать путь. В Python существует два способа его указания: абсолютный и относительный. В предыдущих уроках мы рассматривали импорт модулей без этого разделения. Но для понимания пакетов оно критически важно, поэтому здесь обсудим подробности.
Абсолютный импорт
В абсолютном импорте нужно прописывать полный путь до модуля, включающий все пакеты и подпакеты. Полные пути гарантируют простоту чтения и однозначность — так всем будет понятно, что и откуда импортируется. Чтобы вам было удобнее читать код, во всех примерах выше мы использовали абсолютный импорт.
Внутри директории package лежит модуль constants.py. При абсолютном импорте мы укажем полный путь до него - package.constants.
Относительный импорт
В относительном импорте мы указываем путь не от самого корня проекта, а относительно модуля в котором будет строчка импорта. Для обозначения текущего модуля используется точка, которая означает импорт модуля из текущей директории.
Например, мы работаем с файлом functions.py и хотим импортировать constants.py. При этом functions.py и constants.py хранятся в одной и той же директории. Тогда мы можем указать импорт как from . import constants. Что значит "из текущей директории импортируй модуль constants".
Или для импорта отдельных определений:
Относительный импорт помогает писать быстрее, но слишком сильно запутывает код, что негативно сказывается на читаемости. Именно поэтому в сообществе Python-разработчиков есть распространенный совет для новичков: старайтесь пользоваться абсолютным импортом, даже в самых простых и очевидных случаях.








