что такое модуль init py для чего он нужен
Что такое init.py за что?
Что такое __init__.py для исходного каталога Python?
11 ответов:
Файлы с именем __init__.py используются для обозначения каталогов на диске как каталогов пакетов Python. Если у вас есть файлы
И mydir находится на вашем пути, вы можете импортировать код в module.py как
Файл __init__.py обычно пуст, но может быть использован для экспорта выбранных частей пакета под более удобное имя, функции удержания удобства и т. д. В приведенном выше примере содержимое модуля init можно получить в виде
Пример
Вот пример из одного из моих проектов, в котором я часто импортирую sessionmaker под названием Session в взаимодействуйте с моей базой данных. Я написал пакет «база данных» с несколькими модулями:
Мой __init__.py содержит следующий код:
Поскольку я определяю Session здесь, я могу начать новый сеанс, используя синтаксис ниже. Этот код будет таким же, выполняемым изнутри или снаружи каталога пакета «database».
Дальнейшее чтение
Есть довольно интересная нить reddit, охватывающая соответствующие применения __init__.py здесь:
Большинство считает, что файлы должны быть очень тонкими, чтобы не нарушать философию» явное лучше, чем неявное».
Есть 2 основные причины для __init__.py
Для удобства: другим пользователям не нужно будет знать точное расположение ваших функций в иерархии пакетов.
Тогда другие могут вызвать add () с помощью
Если вы хотите, чтобы что-то было инициализировано; например, ведение журнала (который должен быть помещен на верхний уровень):
Файл __init__.py заставляет Python рассматривать каталоги, содержащие его, как модули.
Кроме того, это первый файл, загружаемый в модуль, поэтому вы можете использовать его для выполнения кода, который вы хотите запускать каждый раз, когда модуль загружается, или указать подмодули, подлежащие экспорту.
Поскольку Python 3.3, __init__.py больше не требуется определять каталоги как импортируемые пакеты Python.
Встроенная поддержка каталогов пакетов, которые не требуют __init__.py файлов маркеров и могут автоматически охватывать несколько сегментов пути (вдохновленные различными сторонними подходами к пакетам пространств имен, как описано в PEP 420)
В Python определение пакета очень простое. Как и Java, иерархическая структура и структура каталогов одинаковы. Но вы должны иметь __init__.py в пакете. Я объясню файл __init__.py на примере ниже:
__init__.py может быть пустым, пока он существует. Это означает, что каталог следует рассматривать как пакет. Конечно, __init__.py также может задать соответствующий контент.
Если мы добавим функцию в module_n1:
Затем мы последовали за пакетом иерархии и вызвали функцию module_n1. Мы можем использовать __init__.py в subPackage_b следующим образом:
__init__.py будет рассматривать каталог, в котором он находится, как загружаемый модуль.
Для тех, кто предпочитает читать код, я помещаю здесь комментарий Двухбитового алхимика.
Что такое __init__.py используется для чего?
В __init__.py для инициализации пакетов Python. Самый простой способ продемонстрировать это-взглянуть на структуру стандартного модуля Python.
Как вы можете видеть в приведенной выше структуре, включение файла __init__.py в каталог указывает интерпретатору Python, что каталог должен рассматриваться как пакет Python
__init__.py может быть Ан пустой файл, но он часто используется для выполнения установки, необходимой для пакета (импорт вещей, загрузка вещей в путь и т. д.).
В приведенном выше примере мы можем сказать, что file.py имеет файл класса. Поэтому без чего-либо в нашем __init__.py вы импортировали бы с помощью этого синтаксиса:
Однако вы можете импортировать файл в свой __init__.py чтобы сделать его доступным на уровне пакета:
__all__ это список, содержащий имена модулей, которые вы хотите импортировать с помощью import * так что посмотрите на наш приведенный выше пример еще раз, если мы хотим импортировать подмодули в подпакет переменная __all__ в subpackage/__init__.py будет иметь вид:
Он будет импортировать submodule1 и submodule2.
Как вы можете видеть, __init__.py может быть очень полезным, помимо своей основной функции указания, что каталог является модулем.
Это облегчает импорт других файлов python. Когда вы помещаете этот файл в каталог (скажем, stuff), содержащий другие файлы py, вы можете сделать что-то вроде импорта материала.другой.
Без этого __init__.py внутри каталога вы не сможете импортировать данные other.py, потому что Python не знает, где находится исходный код для материала, и не может распознать его как пакет.
Он указывает, что пакет должен рассматриваться как модуль, поэтому включите его (даже если он пуст).
Существует также случай, когда вы можете фактически использовать файл __init__.py :
представьте, что у вас есть следующая структура файлов:
И methods.py содержали следующее:
Для использования foo() вам потребуется одно из следующих действий:
Это работает, потому что __init__.py рассматривается как часть пакета.
Исходный код: Lib/json/__init__.py
Как работают импорты в Python
Авторизуйтесь
Как работают импорты в Python
Порой бывает трудно правильно реализовать import с первого раза, особенно если мы хотим добиться правильной работы на плохо совместимых между собой версиях Python 2 и Python 3. Попытаемся разобраться, что из себя представляют импорты в Python и как написать решение, которое подойдёт под обе версии языка.
Содержание
Ключевые моменты
Основные определения
Пример структуры директорий
Что делает import
Основы import и sys.path
Вот как оператор import производит поиск нужного модуля или пакета согласно документации Python:
Программы могут изменять переменную sys.path после её инициализации. Директория, содержащая запускаемый скрипт, помещается в начало поиска перед путём к стандартной библиотеке. Это значит, что скрипты в этой директории будут импортированы вместо модулей с такими же именами в стандартной библиотеке.
Кроме того, импорты в Python регистрозависимы: import Spam и import spam — разные вещи.
Функцию pkgutil.iter_modules() (Python 2 и Python 3) можно использовать, чтобы получить список всех модулей, которые можно импортировать из заданного пути:
Чуть подробнее о sys.path
Документация Python описывает sys.path так:
Список строк, указывающих пути для поиска модулей. Инициализируется из переменной окружения PYTHONPATH и директории по умолчанию, которая зависит от дистрибутива Python.
Документация к интерфейсу командной строки Python добавляет информацию о запуске скриптов из командной строки. В частности, при запуске python
Что init.py для?
что это __init__.py для исходного каталога Python?
11 ответов
файлы с именем __init__.py используются для пометки каталогов на диске как каталогов пакетов Python. Если у вас есть файлы
и mydir находится на вашем пути, вы можете импортировать код в module.py as
если убрать __init__.py file, Python больше не будет искать подмодули внутри этого каталога, поэтому попытки импортировать модуль завершатся неудачей.
на __init__.py файл обычно пуст, но может использоваться для экспортируйте выбранные части пакета под более удобным именем, удерживайте удобные функции и т. д. Учитывая приведенный выше пример, к содержимому модуля init можно получить доступ как
пример
вот пример из одного из моих проектов, в котором я часто импорт sessionmaker под названием Session для взаимодействия с базой данных. Я написал пакет «база данных» с несколькими модулями:
мой __init__.py содержащий следующий код:
так как я определяю Session здесь, я могу начать новый сеанс, используя синтаксис ниже. Этот код будет таким же, выполняемым изнутри или снаружи каталога пакета «база данных».
более дальнеишее чтение
существует довольно интересная нить reddit, охватывающая соответствующие использования __init__.py здесь:
мнение большинства, кажется, что __init__.py файлы должны быть очень тонкими, чтобы избежать нарушения философия» явное лучше, чем неявное».
есть 2 основные причины для __init__.py
для удобства: другим пользователям не нужно будет знать точное местоположение ваших функций в иерархии пакетов.
тогда другие могут вызвать add () по
если вы хотите, чтобы что-то было инициализировано; например, ведение журнала (который должен быть помещен на верхний уровень):
на __init__.py файл делает Python обрабатывать каталоги, содержащие его в качестве модулей.
кроме того, это первый файл, загружаемый в модуль, поэтому вы можете использовать его для выполнения кода, который вы хотите запускать каждый раз при загрузке модуля, или указать подмодули для экспорта.
Начиная С Python 3.3, __init__.py больше не требуется определять каталоги как импортируемые пакеты Python.
встроенная поддержка каталогов пакетов, которые не требуют __init__.py файлы маркеров и могут автоматически охватывать несколько сегментов пути (вдохновленные различными сторонними подходами к пакетам пространств имен, как описано в PEP 420)
в Python определение пакета очень проста. Как и Java, иерархическая структура и структура каталогов одинаковы. Но вы должны иметь __init__.py в пакете. Я объясню __init__.py файл с примером ниже:
__init__.py может быть пустым, пока оно существует. Это указывает на то, что каталог следует рассматривать как пакет. Конечно, __init__.py можно также установить соответствующий контент.
если мы добавим функцию в module_n1:
затем мы последовали за пакетом иерархии и назвали module_n1 функцией. Мы можем использовать __init__.py в subPackage_b вот так:
следовательно, используя * импорт, пакет модуля подлежит __init__.py содержание.
__init__.py будет рассматривать каталог, в котором он находится, как загружаемый модуль.
для людей, которые предпочитают читать код, я ставлю два-бит алхимика комментарий здесь.
что такое __init__.py используется для?
основное использование __init__.py для инициализации пакетов Python. Самый простой способ продемонстрировать это-взглянуть на структуру стандартного модуля Python.
как вы можете видеть в структуре выше включение __init__.py файл в каталоге указывает интерпретатору Python, что каталог должен рассматриваться как пакет Python
__init__.py может быть пустым файлом, но он часто используется для выполнения настройки, необходимой для пакета(импорт вещей, загрузка вещей в путь и т. д.).
одна общая вещь, котор нужно сделать в вашем __init__.py импортировать выбранные классы, функции и т. д. на уровень пакета, чтобы их можно было легко импортировать из пакета.
в примере выше мы можем сказать, что file.py имеет файл класса. Так что ничего в нашем __init__.py импортировать с этот синтаксис:
однако вы можете импортировать файл в свой __init__.py чтобы сделать его доступным на уровне пакета:
еще одна вещь, которую нужно сделать, это на уровне пакета сделать подпакеты / модули доступными с помощью __all__ переменной. Когда переводчиком видит __all__ переменная, определенная в __init__.py он импортирует модули, перечисленные в __all__ переменной, когда вы делаете:
С __all__ переменная заполняется так, когда вы выполняете
он будет импортировать submodule1 и submodule2.
Как видите, __init__.py может быть очень полезно, кроме его основной функции указания, что каталог является модуль.
это облегчает импорт других файлов python. Когда вы разместили этот файл в каталоге (скажем, материал), содержащем другие файлы py, вы можете сделать что-то вроде импорта материала.другой.
без этого __init__.py внутри материала каталога вы не можете импортировать other.py, потому что Python не знает, где находится исходный код для материала, и не может распознать его как пакет.
хотя Python работает без __init__.py файл, который вы все равно должны включить.
он указывает, что пакет должен рассматриваться как модуль, поэтому включите его (даже если он пуст).
существует также случай, когда вы можете использовать :
представьте, что у вас есть следующая структура файлов:
использовать foo() вам понадобится одно из следующих действий:
это работает, потому что __init__.py рассматривается как часть пакета.
некоторые пакеты Python действительно делают это. Пример с JSON, где работает import json фактически импорта __init__.py С json пакета (смотрите файловую структуру пакета здесь):
исходный код: Lib/json/__init__.py
Ликбез по пакетам и шпаргалка по модулям в Python
О чём пойдёт речь
Как вы, возможно знаете, код на Python хранится в модулях (modules), которые могут быть объединены в пакеты (packages). Это руководство призвано подробно рассказать именно о пакетах, однако совсем не упомянуть модули нельзя, поэтому я немного расскажу и о них. Многое из того, что применимо к модулям, справедливо и для пакетов, особенно если принять во внимание тот факт, что каждый, как правило, ведёт себя как модуль.
Кратко о модулях
Модуль в Python — это файл с кодом. Во время же исполнения модуль представлен соответствующим объектом, атрибутами которого являются:
При этом определения и импортированные сущности ничем друг от друга не отличаются: и то, и другое — это всего лишь именованные ссылки на некоторые объекты первого класса (такие, которые могут быть переданы из одного участка кода в другой как обычные значения).
Такое единообразие удобно, например, при рефакторинге: мы можем разделить один разросшийся модуль на несколько, а потом импортировать вынесенные определения в оригинальный модуль. При этом с точки зрения внешнего наблюдателя переработанный модуль будет иметь те же атрибуты, которые имел до внесения изменений, а значит у пользователей модуля ничего в коде не сломается.
Модули и видимость содержимого
В Python нет настоящего сокрытия атрибутов объектов, поэтому и атрибуты объекта модуля так или иначе всегда доступны после импорта последнего. Однако существует ряд соглашений, которые влияют на процесс импортирования и поведение инструментов, работающих с кодом.
Так атрибуты, имя которых начинается с одиночного подчёркивания, считаются как бы помеченными «для внутреннего использования», и обычно не отображаются в IDE при обращению к объекту «через точку». И linter обычно предупреждает об использовании таких атрибутов, мол, «небезопасно!». «Опасность» состоит в том, что автор кода имеет полное право изменять состав таких атрибутов без уведомления пользователей кода. Поэтому программист, использовавший в своём коде приватные части чужого кода рискует в какой-то момент получить код, который перестанет работать при обновлении сторонней библиотеки.
Итак, мы можем определять публичные атрибуты модуля, приватные атрибуты (так называют упомянутые выше атрибуты «для внутреннего пользования»). И данное разделение касается не только определений, содержащихся в самом модуле, но и импортируемых сущностей. Ведь все импортированные объекты становятся атрибутами и того модуля, в который они импортированы.
Живой пример видимости атрибутов модулей.
Рассмотрим пример, демонстрирующий всё вышеописанное. Пусть у нас будет два файла:
А эти атрибуты не будут видны:
Импорт import other_module я не рассматриваю как тривиальный случай.
Теперь рассмотрим импорт всего содержимого module:
Последствия импорта from other_module import * тоже очевидны и я их не рассматриваю.
Наконец-то, пакеты!
Импортирование пакетов
Пакет с единственным модулем __init__.py при импорте ведёт себя как обычный модуль. Содержимое инициализирующего модуля определяет атрибуты объекта пакета.
Прочие модули пакета и вложенные пакеты не импортируются автоматически вместе с пакетом-родителем, но могут быть импортированы отдельно с указанием полного имени. Важный момент: при импортировании вложенного модуля всегда сначала импортируются модули инициализации всех родительских пакетов (если оные ещё ни разу не импортировались, но об этом я расскажу ниже).
Рассмотрим, к примеру, следующую структуру директорий и файлов:
Так что же, если мы загрузим парочку вложенных модулей, то для каждого будет выполняться загрузка всех __init__.py по дороге? Не будет! Подсистема интерпретатора, отвечающая за загрузку модулей, кэширует уже загруженные пакеты и модули. Каждый конкретный модуль загружается ровно один раз, в том числе и инициализирующие модули __init__.py (короткие имена модулей хоть и одинаковы, но полные имена всегда разные). Все последующие импортирования модуля не приводят к его загрузке, только лишь нужные атрибуты копируются в соответствующие области видимости.
Пакеты и __all__
Вот структура пакета:
Файл же package/__init__.py содержит следующее (и только это!):
Указанный автоматизм достаточно ограничен: не работает «вглубь», например — не импортирует «через звёздочку» указанные модули и подпакеты. Если же вам вдруг такого захочется, вы всегда сможете на соответствующих уровнях в __init__.py сделать from x import * и получить в корневом пакете плоскую область видимости со всем нужным содержимым. Но такое нужно довольно редко, потому что «не помогает» ни IDE, ни ручному поиску по коду. Впрочем, знать о фиче и иметь её в виду — не вредно, как мне кажется.
Изучайте Python на Хекслете Первые курсы в профессии Python-программист доступны бесплатно сразу после регистрации. Начните сегодня, учитесь в комфортном для вас темпе.
Пакеты, модули и точки входа
Более того, модули __main__ нельзя импортировать обычным способом, поэтому можно не бояться случайного импорта и писать команды прямо на верхнем уровне: всё равно странно в модуле с именем __main__ проверять, что его имя равно __main__ (хе-хе!).
PEP 420, или неявные пространства имён
Раз уж развёл ликбез, расскажу и про эту штуку.
Долгое время в Python пакеты были обязаны иметь файл __init__.py — наличие этого файла позволяло отличить пакет от обычной директории с модулями (с которыми Python работать не мог). Но с версии Python3.3 вступил в силу PEP 420, позволяющий создавать пространства имён «на вырост».
Тут стоит отметить, что с полноценными пакетами подобное не срабатывало ранее и не будет работать в будущем. Если среди путей пакет с модулем инициализации находится в первый раз, все последующие пакеты с тем же именем будут проигнорированы. Это защищает вас от смешивания сторонних пакетов с системными. И даже просто от ошибок именования: назвав пакет так же, как называется встроенный пакет или модуль, вы получите ошибку — ваши определения не будут импортироваться.
Пакеты — пространства имён (Namespace Packages, NP) — а именно так называются пакеты без инициализации — не могут объединяться с полноценными пакетами, поэтому добавить что-то в системный пакет вам также не удастся. И тут всё защищено!
Важно: помните, если встретятся обычный пакет и NP с одинаковым именем, то победит обычный пакет! А NP, сколько бы их не было, не будут загружены!
Циклические импорты
Если же приспичивает, и импортировать что-то «ну очень нужно», то можно попробовать обойтись локальным импортом:
Да, это костыль. Но иногда полезный. В идеале — до ближайшего большого рефакторинга. Поэтому настраивайте linter на ловлю локальных импортов и стремитесь убирать такие костыли хоть когда-нибудь!
Поиск пакетов и модулей
Пайтон ищет модули и пакеты в директориях, во время исполнения перечисленных в списке sys.path — по порядку от первого пути к последнему.
В этом списке пути до стандартных библиотек обычно расположены раньше, чем директории со сторонними пакетами, чтобы нельзя было случайно заменить стандартный пакет сторонним (помним: кто первый, того и тапки — среди нескольких с одинаковыми именами загружается первый попавшийся пакет).
Обычно пути трогать не нужно, всё вполне нормально «работает само». Но если очень хочется, то путей у вас несколько:
Первый способ — простой и понятный. Не сложнее добавления пути до исполняемых файлов в PATH (даже синтаксис тот же).
Кстати, когда вы используете виртуальные окружения, sys.path будет содержать пути до локальных копий стандартных библиотек. Именно это позволяет виртуальному окружению быть самодостаточным (работать на любой машине с подходящей ОС — даже без установленного в систему Python!).
Что не было раскрыто?
Я специально не стал рассказывать про
Темы эти насколько интересны, настолько и велики. На наше счастье, самим разбираться в такой тонкой и сложной машинерии приходится редко. Мы просто пользуемся готовыми магическими артефактами, а зачаровывают их другие 🙂 Если же вы захотите научиться магии, документация вам в руки.
Пакеты — Основы языка Python
Мы уже знаем, что в Python код хранится в отдельных файлах, называемых модулями. Но если начать делить код достаточно большого проекта на модули, то довольно быстро может возникнуть желание сгруппировать несколько модулей «по смыслу». Или же мы захотим вынести часть модулей из проекта с целью их использования в других проектах. Для объединения модулей в группы служат пакеты (packages).
Итак, пакет — это директория (далее «каталог») с файлами модулей, имеющая имя в формате «snake_case» и содержащая, помимо прочего, специальный модуль с именем » __init__.py «. Именно наличие этого специального файла подсказывает интерпретатору Python, что каталог следует воспринимать именно как пакет.
Простейший пакет
Давайте рассмотрим пример простейшего пакета. Пусть пакет состоит из каталога package и модуля __init__.py внутри этого каталога:
Файл __init__.py пусть содержит код:
Это, хотя и небольшой, но уже полноценный пакет. Его можно импортировать так же, как мы импортировали бы модуль:
Заметьте — мы не импортировали файл __init__.py непосредственно. При первом обращении к пакету Python автоматически импортирует модуль __init__.py в этом пакете. Поэтому, очевидно, нельзя импортировать «просто каталог» — ведь каталог без файла __init__.py не будет полноценным пакетом!
Содержимое пакета
С простым пакетом всё ясно — его можно использовать как модуль. Но давайте уже перейдём к группировке в пакете нескольких модулей! Для этого в пакет положим ещё два модуля:
Содержимое модуля constants.py :
Содержимое модуля functions.py :
Этот вариант самый понятный: в строчке вызова функции greet сразу видно, откуда пришла функция, а откуда — её аргумент. Но писать имя пакета и имя модуля каждый раз — утомительно! Давайте импортируем саму функцию и аргумент:
Так строчка вызова функции выглядит гораздо лучше! Но помните, что тому, кто будет читать этот код в дальнейшем, потребуется посмотреть в блок импортов, чтобы узнать, откуда функция и константа появились.
Пакеты и импорты
Импорты в Python бывают двух видов: абсолютные и относительные. Понимание разницы становится особенно важным, когда вы начинаете работать с пакетами.
Абсолютные импорты
Абсолютный импорт выглядит как указание полного пути до модуля, включающего все пакеты и подпакеты (subpackages) — да, любой пакет может содержать не только модули, но и вложенные пакеты! Полные пути гарантируют однозначность: интерпретатору всегда понятно, что и откуда импортируется, и читать такие импорты проще.
Относительные импорты
Относительные импорты выглядят так:
Какие же импорты использовать?
Я придерживаюсь мнения большинства: нужно всегда использовать абсолютные импорты! Даже если вы внутри одного пакета один модуль импортируете в другой. Да, при использовании абсолютных импортов приходится писать чуть больше. Но понятность кода — слишком полезное свойство, чтобы от него отказываться!
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты.
Нашли опечатку или неточность?
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Что-то не получается или материал кажется сложным?
Загляните в раздел «Обсуждение»:
Об обучении на Хекслете
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.