Не требуется ли __init__.py для пакетов в Python 3?
Я использую Python 3.5.1. Я прочитал документ и раздел пакета здесь: https://docs.python.org/3/tutorial/modules.html
Теперь у меня есть следующая структура:
/home/wujek/Playground/a/b/module.py
module.py
:
class Foo:
def __init__(self):
print('initializing Foo')
Теперь, пока в /home/wujek/Playground
:
~/Playground $ python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x100a8f0b8>
Точно так же сейчас в доме, супер-папка Playground
:
~ $ PYTHONPATH=Playground python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x10a5fee10>
На самом деле, я могу делать разные вещи:
~ $ PYTHONPATH=Playground python3
>>> import a
>>> import a.b
>>> import Playground.a.b
Почему это работает? Я хотя там должен был быть __init__.py
файлы (пустые будут работать) в обоих a
а также b
за module.py
быть импортируемым, когда путь Python указывает на Playground
папка?
Похоже, это изменилось с Python 2.7:
~ $ PYTHONPATH=Playground python
>>> import a
ImportError: No module named a
>>> import a.b
ImportError: No module named a.b
>>> import a.b.module
ImportError: No module named a.b.module
С __init__.py
в обоих ~/Playground/a
а также ~/Playground/a/b
это работает отлично.
2 ответа
В Python 3.3+ есть неявные пакеты пространства имен, которые позволяют создавать пакеты без __init__.py
файл.
Разрешение неявных пакетов пространства имен означает, что требование предоставить
__init__.py
файл может быть полностью удален, и это может повлиять...
Старый способ с __init__.py
файлы все еще работают как в Python 2.
@ Ответ Майка правильный, но слишком неточный. Это правда, что Python 3.3+ поддерживает неявные пакеты пространства имен, что позволяет создавать пакеты без __init__.py
файл.
Однако это относится ТОЛЬКО к файлам EMPTY __init__.py. Таким образом, файлы EMPTY __init__.py больше не нужны и могут быть опущены. Если вы хотите импортировать модули в пакет, вам все равно требуется файл __init__.py, в котором перечислены все импортируемые файлы.
Пример структуры каталогов:
parent_package/
__init__.py <- EMPTY, NOT NECESSARY in Python 3.3+
child_package/
__init__.py <- STILL REQUIRED to import all child modules
child1.py
child2.py
child3.py
__init__
файл в child_package
:
import child1
import child2
import child3
Если у вас есть setup.py
и вы используете find_packages()
необходимо иметь __init__.py
в каждом каталоге для автоматического поиска пакетов
Пакеты распознаются, только если они включают
__init__.py
файл
Я бы сказал, что нужно опустить __init__.py
только если кто-то хочет иметь неявный пакет пространства имен. Если вы не знаете, что это значит, вы, вероятно, не хотите этого, и поэтому вы должны продолжать использовать __init__.py
даже в Python 3.
По моему опыту, даже с python 3.3+ пустой
__init__.py
все еще иногда требуется. Одна из ситуаций - когда вы хотите назвать подпапку пакетом. Например, когда я бежал
python -m test.foo
, это не сработало, пока я не создал пустой
__init__.py
в тестовой папке. И я говорю о версии 3.6.6, которая появилась довольно недавно.
Кроме того, даже по причинам совместимости с существующим исходным кодом или руководящими принципами проекта, неплохо иметь пустой
__init__.py
в папке вашего пакета.