Обычно код в больших проектах делят на модули — отдельные файлы, в которых хранится код в 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):
print('Hello, ' + who + '!')
Теперь в пакете есть не только __init__.py
, но и еще два модуля — теперь их можно импортировать.
В главе про модули упоминались два распространенных варианта:
Применим оба способа импорта — но теперь уже не к модулям, а к пакетам.
Квалифицированный импорт помогает писать читабельный код. Прочитав строчку вызова функции, другой разработчик сразу поймет, откуда пришли сама функция и ее аргумент. В этом примере квалифицированный импорт выглядит так:
import package.functions
import package.constants
package.functions.greet(package.constants.PERSON) # => Hello, Alice!
Импорт отдельных определений удобнее в работе, потому что вам не придется каждый раз прописывать имя пакета и модуля. С другой стороны, другим разработчикам будет сложнее читать код. Чтобы узнать, откуда пришли функция и константа, им придется смотреть в блок импортов.
Попробуем импортировать отдельные определения, то есть саму функцию и аргумент:
from package.functions import greet
from package.constants import PERSON
greet(PERSON) # => Hello, Alice!
Кроме того, импорты в Python бывают двух видов:
В предыдущих уроках мы рассматривали импорт модулей без этого разделения. Но для понимания пакетов оно критически важно, поэтому здесь обсудим подробности.
В абсолютном импорте нужно прописывать полный путь до модуля, включающего все пакеты и подпакеты. Полные пути гарантируют простоту чтения и однозначность — так всем будет понятно, что и откуда импортируется. Чтобы вам было удобнее читать код, во всех примерах выше мы использовали абсолютный импорт.
Относительные импорты выглядят так:
from . import module
from .module import function
from .subpackage.module import CONSTANT
В относительном импорте используется точка, которая означает импорт модуля из текущей директории.
Например, мы работаем в файле main.py
и хотим импортировать .module
. При этом мы знаем, что main.py
и .module
хранятся в одной и той же директории. Тогда можно не прописывать абсолютный путь к .module
, а воспользоваться . import
. По этой точке Python автоматически определит, что и откуда мы хотим импортировать.
Относительный импорт помогает писать быстрее, но слишком сильно запутывает код и негативно сказывается на читаемости. Именно поэтому в сообществе Python-разработчиков есть распространенный совет для новичков: старайтесь пользоваться абсолютным импортом, даже в самых простых и очевидных случаях.
Вам ответят команда поддержки Хекслета или другие студенты.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.
Зарегистрируйтесь или войдите в свой аккаунт