Я использую 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
все работает нормально.
источник
Zen Of Python
строке 2:Explicit is better than implicit.
....__init__.py
, иногда нет. В Python 3, когда мне нужны эти вещи, я создаю новый__init__.py
с конкретным кодом, в противном случае я не делаю. Это полезно знать, визуально, какие пакеты имеют пользовательский init. Вместо этого в Python 2 мне всегда нужно помещать__init__.py
(часто пустой), делая их много, и, наконец, сложнее запомнить, где вы поместили свой код инициализации. Это также должно соответствовать «Должен быть один - и желательно только один - очевидный способ сделать это».ВАЖНЫЙ
@ Ответ Майка правильный, но слишком неточный. Это правда, что Python 3.3+ поддерживает неявные пакеты пространства имен, что позволяет создавать пакеты без
__init__.py
файла.Это, однако, относится ТОЛЬКО к ПУСТЫМ
__init__.py
файлам. Таким образом, файлы EMPTY__init__.py
больше не нужны и могут быть опущены. Если вы хотите запустить определенный сценарий инициализации при импорте пакета или любого из его модулей или подпакетов, вам все равно требуется__init__.py
файл. Это отличный ответ на переполнение стека, объясняющий, почему вы захотите использовать__init__.py
файл для дальнейшей инициализации, если вам интересно, почему это в любом случае полезно.Пример структуры каталогов:
parent_package/child_package/__init__.py
:ПРИМЕРЫ
Приведенные ниже примеры демонстрируют, как выполняется скрипт инициализации при
child_package
импорте одного или одного из его модулей.Пример 1 :
Пример 2 :
источник
run_script.py
тот же каталог, чтоparent_package
и у меня, но я могу импортировать какfrom parent_package.child_package import child1
без__init__.py
?child1.py
,child2.py
вместо того , чтобы просто собрать их код в__init__
.py напрямую.__init__
быть относительный импорт , то естьfrom . import child1
? Абсолютный импорт дает мнеModuleNotFoundError
(в Python 3.6)__init__.py
иногда все еще требуется пустое место , например, когда вы хотите сослаться на подпапку как на пакет. Например, если я запустилpython -m test.foo
его, он не работал, пока я не создал пустую__init__.py
папку в тестовой папке. И я говорю о версии 3.6.6 здесь!Если у вас есть
setup.py
в вашем проекте, и вы используетеfind_packages()
в нем, необходимо иметь__init__.py
файл в каждом каталоге для автоматического поиска пакетов.UPD : если вы хотите использовать неявные пакеты пространства имен без использования
__init__.py
, просто используйтеfind_namespace_packages()
вместо этогоДокументы
источник
Я бы сказал, что следует исключить
__init__.py
только один, если вы хотите иметь неявный пакет пространства имен . Если вы не знаете, что это значит, вы, вероятно, не хотите этого, и поэтому вам следует продолжать использовать__init__.py
даже в Python 3.источник