Ответ 1
Там очень хорошее обсуждение этого вопроса в этом ответе, и вы, вероятно, должны быть знакомы с PEP 420, чтобы уточнить разницу между регулярными пакетами (используйте __init__.py
) и пакеты пространства имен (не).
Что я предлагаю в качестве ответа, это сочетание чтения, ссылок и мнения. Никаких претензий к тому, чтобы быть "каноническим" или "питоническим" здесь.
Используются ли [инициализации] случаи использования, все еще имеющие отношение к python 3.3 +?
Да. Возьмите пример в качестве варианта использования, когда автор пакета хочет внести несколько вещей в пространство имен корневых пакетов, чтобы пользователь не должен был заботиться о своей внутренней структуре.
Другим примером является создание иерархии модулей. Эта ссылка (O'Reilly) фактически говорит:
Цель файлов
__init__.py
состоит в том, чтобы включить дополнительный код инициализации, который выполняется с разными уровнями пакета.
Они рассматривают пакеты пространства имен в этом обсуждении, но продолжают:
При прочих равных условиях, включите файлы
__init__.py
, если вы только начинаете с создания нового пакета.
Итак, для вашего второго вопроса
лучше всего избегать
__init__.py
, если это возможно?
Нет, если вы не намерены создавать пакет пространства имен, а не обычный пакет, и в этом случае вы не должны использовать __init__.py
.
Зачем вам это нужно? Ссылка O'Reilly имеет самый ясный пример Я видел, почему пакеты пространства имен классные, что позволяет свернуть пространства имен от отдельных, независимо поддерживаемые пакеты:
foo-package/
spam/
blah.py
bar-package/
spam/
grok.py
Что позволяет
>>> import sys
>>> sys.path.extend(['foo-package', 'bar-package'])
>>> import spam.blah
>>> import spam.grok
>>>
Таким образом, каждый может расширить пространство имен своим собственным кодом. Круто.