Найти в Дзене
Джун Линуксович

Импорты в Python

Краткая выжимка про относительные и абсолютные импорты. Советую прочесть новичкам и тем, у кого возникли сложности в этом разделе. Итак. Чтобы программа стала более понятной, ее разбивают на классы, где каждый класс отвечает за определенные вещи. Классы не хранят в одном файле, их раскидывают по разным файлам. Файлов может образоваться много, поэтому их группируют по смыслу, по папкам. Мы запускаем проект одним файлом. Его называют исполняемым. Принято его называть main.py. Кроме него есть и другие файлы в проекте с пайтоновским расширением, т.е. по сути они могут быть запущены(но запускать их отдельно нет смысла). Эти файлы для своей работы, также, как и main могут иметь импорты. Главный, исполняемый файл всегда хранят в корне проекта, т.е. мы зашли в папку и он сразу на виду - main.py. Это сделано конечно же для удобства, чтобы мы не вспоминали в какой папке он запрятан. Если это файл находится в корне проекта, т.е. на самом верху, то импортами он лезет вглубь папок, ищет нужные фа

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

Итак. Чтобы программа стала более понятной, ее разбивают на классы, где каждый класс отвечает за определенные вещи. Классы не хранят в одном файле, их раскидывают по разным файлам. Файлов может образоваться много, поэтому их группируют по смыслу, по папкам. Мы запускаем проект одним файлом. Его называют исполняемым. Принято его называть main.py. Кроме него есть и другие файлы в проекте с пайтоновским расширением, т.е. по сути они могут быть запущены(но запускать их отдельно нет смысла). Эти файлы для своей работы, также, как и main могут иметь импорты.

Главный, исполняемый файл всегда хранят в корне проекта, т.е. мы зашли в папку и он сразу на виду - main.py. Это сделано конечно же для удобства, чтобы мы не вспоминали в какой папке он запрятан. Если это файл находится в корне проекта, т.е. на самом верху, то импортами он лезет вглубь папок, ищет нужные файлы и достает из них объекты (абсолютный импорт). Т.е. находясь в самом верху ему нет смысла импортами лезть еще выше. При первом приближении можно сказать, что

- абсолютный импорт копает в глубь папок

- тогда относительный строит путь наверх, выбираясь из своей папки.

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

Идем дальше. Запуская исполняемый файл, мы импортами запускаем и код, который в этих файлах содержится. Иногда в них тоже могут быть импорты. Как же в данном случае прописывать импорт в таких файлах? Есть 2 возможных варианта. Можно прописать абсолютный (пишем его так, как буд-то мы сейчас находимся с исполняемом файле main.py ), либо относительный - смотрим где наш текущий файл находится и простраиваем путь наверх из папки согласно правил.

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

абсолютный можно прописывать как в main.py, так и в других файлах

относительный можно прописать в любых, файлах, кроме main.py

Есть ограничения и на относительные импорты - они не могут подниматься вверх до уровня, где расположен главный исполняемый файл. Почему? Тут тоже все логично. А зачем? Какой смысл помещать файл с нужными нам классами на уровень main.py или выше, вне проекта? Правильно, бессмыслица. Сами правила импортов диктуют нам как нужно строить проект должным образом, дабы избежать в будущем не нужных проблем.

основная схема абсолютных импортов: from папка.закопанный_в_эту_папку_файл import переменная или функция

основная схема относительных импортов(1 точка - эта же папка, подняться выше 2 точки и т.д.)

Примеры

main.py:

import pack_2.pack_21.file_211

file_21.py:

def func_1():

return 25

file_211.py

# from ..file21 import func_1 #относительный импорт

from pack_2.file21 import func_1 #абсолютный импорт

print(func_1())

В file_211.py прописаны 2 импорта (абсолютный и относительный). Они идентичны и приводят к одному и тому же результату. Попробуйте попереме

нно их запустить, закоментировав другой