Используя __init__.py

У меня возникают трудности с пониманием сценариев использования или целей проектирования файлов python __init__.py в моих проектах.

Предположим, что у меня есть "модельный" каталог (относится к пакету), который содержит следующие файлы

  • __init__.py
  • meta.py
  • solrmodel.py
  • mongomodel.py
  • samodel.py

Я нашел два способа использования __init__.py:

  • У меня есть общее определение, которое необходимо использовать в solrmodel.py, mongomodel.py, samodel.py. Могу ли я использовать __init__.py как базовое/общее определение для всех классов * model.py? Это означает, что мне нужно импортировать model/__init__.py.

  • Или, __init__.py должен импортировать определения solrmodel.py, mongomodel.py, samodel.py в свой собственный, и это позволяет легко импортировать классы или выполнять функцию следующим образом:

    # file: __init__.py
    
    from mongomodel import *
    from solrmodel import *
    from samodel import *
    

    (Я знаю, что import * не рекомендуется, и я просто использовал его как соглашение)

Я не мог решить между двумя вышеуказанными сценариями. Есть ли больше сценариев использования для __init__.py и вы можете объяснить использование?

Ответ 1

Подавляющее большинство файлов __init__.py, которые я пишу, пуст, потому что многим пакетам нечего инициализировать.

Один пример, в котором я могу начать инициализацию, - это когда во время загрузки пакета я хочу прочитать кучу данных раз и навсегда (из файлов, БД или сети, скажем) - в этом случае это намного лучше, чтобы сделать это чтение в частной функции в пакете __init__.py вместо того, чтобы иметь отдельный "модуль инициализации" и избыточно импортировать этот модуль из каждого отдельного реального модуля в пакете (бесполезно повторяющийся и ошибка -prone: это, очевидно, случай, когда полагаться на язык, гарантируя, что пакет __init__.py загружается один раз, прежде чем какой-либо модуль в пакете, очевидно, намного больше Pythonic!).

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

Ответ 2

Содержимое __init__.py импортируется при импорте модуля внутри пакета.

Вы игнорируете третий сценарий, который заключается в том, чтобы поместить общие части в отдельный модуль, а затем импортировать другие модули, оставив __init__.py для вещей, которые будут использоваться вне пакета. Это практика, которую я обычно придерживаюсь.