Зарегистрируйтесь, чтобы продолжить обучение

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

Обычно код в больших проектах делят на модули — отдельные файлы, в которых хранится код на Python. Но иногда и этого разделения недостаточно. Часто модули хочется сгруппировать «по смыслу» или сформировать отдельную группу модулей, чтобы использовать их в других проектах.

В таких случаях помогают пакеты — группы модулей. В особенно больших проектах используются еще и подпакеты внутри пакетов, но на этой теме мы пока не будем останавливаться. В этом уроке разберемся, как создавать пакеты и добавлять в них модули. Также поговорим о том, какими способами можно импортировать пакеты в проект.

Создаем пакет

С точки зрения структуры пакет — это директория с файлами модулей, с названием в формате 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-файла не будет считаться пакетом.

Добавляем модули в пакет

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

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

Чтобы было понятнее, рассмотрим содержимое модуля constants.py:

# file constants.py
PERSON = "Alice"

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

# file functions.py
def greet(who: str) -> None:
    print("Hello, " + who + "!")

Теперь в пакете есть не только __init__.py, но и еще два модуля — теперь их можно импортировать.

Как импортировать модули из пакетов

Импорт модулей из пакета выглядит так же, но к имени модуля приписывается имя пакета. То есть указывается путь до модуля.

Например, импорт всего модуля выглядит так:

import package.functions
import package.constants

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

К названию модуля functions приставляется название пакета package, где этот модуль и лежит. Обратите внимание, что путь указывается через точку.

Попробуем импортировать отдельные определения, то есть саму функцию и аргумент:

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

greet(PERSON)  # => Hello, Alice!

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

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

В абсолютном импорте нужно прописывать полный путь до модуля, включающий все пакеты и подпакеты. Полные пути гарантируют простоту чтения и однозначность — так всем будет понятно, что и откуда импортируется. Чтобы вам было удобнее читать код, во всех примерах выше мы использовали абсолютный импорт.

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

Внутри директории package лежит модуль constants.py. При абсолютном импорте мы укажем полный путь до него - package.constants.

from package.functions import greet

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

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

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

Например, мы работаем с файлом functions.py и хотим импортировать constants.py. При этом functions.py и constants.py хранятся в одной и той же директории. Тогда мы можем указать импорт как from . import constants. Что значит "из текущей директории импортируй модуль constants".

# functions.py
from . import constants

Или для импорта отдельных определений:

# functions.py
from .constants import PERSON

Относительный импорт помогает писать быстрее, но слишком сильно запутывает код, что негативно сказывается на читаемости. Именно поэтому в сообществе Python-разработчиков есть распространенный совет для новичков: старайтесь пользоваться абсолютным импортом, даже в самых простых и очевидных случаях.

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff