__Init__.py не требуется для пакетов в Python 3.3+
Я использую Python 3.5.1. Я прочитал документ и раздел пакета здесь: https://docs.python.org/3/tutorial/modules.html#packages
Теперь у меня есть следующая структура:
/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
он отлично работает.
Ответы
Ответ 1
Python 3. 3+ имеет неявные пакеты пространства имен, которые позволяют ему создавать пакеты без файла __init__.py
.
Разрешение неявных пакетов пространства имен означает, что требование предоставить файл __init__.py
может быть полностью отброшено и затронуто....
Старый способ с файлами __init__.py
прежнему работает как в Python 2.
Ответ 2
ВАЖНЫЙ
@Майк ответ правильный, но слишком неточный. Это правда, что Python 3. 3+ поддерживает неявные пакеты пространства имен, что позволяет ему создавать пакет без файла __init__.py
.
Это, однако, относится ТОЛЬКО к файлам EMPTY __init__.py
. Таким образом, файлы EMPTY __init__.py
больше не нужны и могут быть опущены. Если вы хотите запустить определенный сценарий инициализации при импорте пакета или любого из его модулей или подпакетов, вам все равно требуется файл __init__.py
. Это отличный ответ о переполнении стека, почему вы захотите использовать файл __init__.py
для дальнейшей инициализации, если вам интересно, почему это в любом случае полезно.
Пример структуры каталогов:
parent_package/
__init__.py <- EMPTY, NOT NECESSARY in Python 3.3+
child_package/
__init__.py <- STILL REQUIRED if you want to run an initialization script
child1.py
child2.py
child3.py
parent_package/child_package/__init__.py
:
print("from parent")
ПРИМЕРЫ
Приведенные ниже примеры демонстрируют, как выполняется скрипт инициализации при child_package
или одного из его модулей.
Пример 1:
from parent_package import child_package # prints "from parent"
Пример 2:
from parent_package.child_package import child1 # prints "from parent"
Ответ 3
Если у вас есть setup.py
в вашем проекте и вы используете find_packages()
внутри него, необходимо иметь файл __init__.py
в каждом каталоге для автоматического поиска пакетов.
Пакеты распознаются, только если они содержат файл __init__.py
Документы
Ответ 4
Я бы сказал, что __init__.py
следует опускать, только если вы хотите иметь неявный пакет пространства имен. Если вы не знаете, что это значит, вы, вероятно, не хотите этого, и поэтому вам следует продолжать использовать __init__.py
даже в Python 3.