Как работает __init__.py?

Цитирую документацию: https://docs.python.org/3/tutorial/modules.html#pa...
The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path

Допустим, в одном каталоге из sys.path есть папка package1. Его структура:
package1/
     sub_package1/
          module1.py
     sub_package2/
          module2.py

Далее в интерпретаторе я пишу import package1. Почему нельзя просто найти папку package1 и импортировать её без __init__.py? (т.е, почему питону не понятно, что папка с модулями и с нужным названием - это пакет, который нужно импортировать?) Можете привести пример случая prevent directories with a common name, such as string, from unintentionally hiding valid modules или случая, когда __init__.py полезен?
  • Вопрос задан
  • 52810 просмотров
Решения вопроса 2
1. Питон может искать модули в нескольких папких в порядке очередности (в том числе по путям в PYTHON_PATH).
2. Представьте что по одному из путей у вас вот так:
5b068f8fd81f8672868800.png
а по другому вот так:
5b068fd63bfa3737841777.png
3. Вы импортируете модуль string, но первой по приоритету обрабатывается директория с папкой string. А у вас там например вообще не питоновский код, а документация какая-нибудь. Вы на самом деле хотите заимпортить string.py из второй папки, но интерпретатор будет думать что нужно взять директорию, и выдаст ошибку (скажет что мол не является это валидным пакетом или что-то в таком духе).
4. Чтобы такого не было, разработчики решили что вы должны явно помечать, что хотите чтобы папка считалась пакетом. Это тоже самое что помечать файлы с кодом на питоне расширением .py - вы же не ждёте что интерпретатор будет воспринимать .txt-шники как модули на питоне? То же самое и с папкой.

Ну и да, как уже упомянул Вячеслав , __init__.py вовсе не обязательно должен быть пустым, например там могут быть реэкспорты.
Ответ написан
Комментировать
Nirail
@Nirail
Дайте мне повод и я во все решу
Кроме того, что он позволяет питону интерпретировать директория как пакет, в __init__.py может быть включен различный код инициализации, например:
  • переменная __all__
  • проверка ограничений при использовании пакета
  • сообщение о deprecated
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
DMGarikk
@DMGarikk
Lead Software Developer
Перечитав комментарии, я думаю что правильный ответ такой:
да потому что разработчики решили сделать именно так, решили сделать маркером пакета этот файл... а сейчас уже все привыкли
точно также как в других языках фигурные скобки, begin/end, точка с запятой... без которых питон обходится, а что другим языкам мешает? вот по этой-же самой причине
Ответ написан
Комментировать
SowingSadness
@SowingSadness
web-разработчик
Если в папке нет __init__.py то это не пакет.
Грубо говоря, __init__.py нужен для того что бы можно было загружать именно пакет и модель работы пакетов функционировала.

import package1
from package1.sub_package1 import *
Ответ написан
@Pixilys
С версии Python 3.3 + . Этот файлик больше не нужен.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы