Python – почему я могу импортировать модули без __init__.py?

Я новичок в Python, и я до сих пор не могу понять, зачем нам нужен файл __init__.py для импорта модулей. Я рассмотрел другие вопросы и ответы, например.

Меня смущает то, что я могу импортировать свои модули без __init__py , поэтому зачем мне это вообще нужно ?

Мой пример,

 index.py modules/ hello/ hello.py HelloWorld.py 

index.py,

 import os import sys root = os.path.dirname(__file__) sys.path.append(root + "/modules/hello") # IMPORTS MODULES from hello import hello from HelloWorld import HelloWorld def application(environ, start_response): results = [] results.append(hello()) helloWorld = HelloWorld() results.append(helloWorld.sayHello()) output = "<br/>".join(results) response_body = output status = '200 OK' response_headers = [('Content-Type', 'text/html'), ('Content-Length', str(len(response_body)))] start_response(status, response_headers) return [response_body] 

Модули / привет / hello.py,

 def hello(): return 'Hello World from hello.py!' 

Модули / привет / HelloWorld.py,

 # define a class class HelloWorld: def __init__(self): self.message = 'Hello World from HelloWorld.py!' def sayHello(self): return self.message 

Результат,

 Hello World from hello.py! Hello World from HelloWorld.py! 

Что нужно, так это только эти две строки,

 root = os.path.dirname(__file__) sys.path.append(root + "/modules/hello") 

Без какой-либо __init__py . Может кто-нибудь объяснить, почему он работает таким образом?

Если __init__py является правильным способом, что мне делать / изменять в моем коде?

5 Solutions collect form web for “Python – почему я могу импортировать модули без __init__.py?”

__init__.py – для пакетов . Пакет содержит набор связанных модулей. Если у вас только один модуль, который вы хотите использовать, вам не нужно использовать __init__.py ; просто поместите единственный .py файл где-нибудь на системный путь, и вы можете его импортировать.

Цель пакетов – не только позволить вам импортировать модули внутри них. Это объединение групп вместе. Главное преимущество этого заключается в том, что если модуль находится внутри пакета, то этот модуль может импортировать другие модули из пакета с использованием относительного импорта. Если у вас есть foo.py и bar.py в одном пакете, то foo может просто сделать это from . import bar from . import bar . Это делает импорт внутри пакета более компактным и проще реорганизовать, если вы реструктурируете пакет или измените его имя.

Кроме того, очевидная выгода. , , если вы сделаете это пакетом, вам не нужно делать этот материал sys.path каждый раз, когда вы хотите что-то импортировать из него.

Я думаю, что это может быть связано с используемой версией Python. Я сделал несколько экспериментов и выяснил, что имеет следующую структуру:

 jedrzej@jedrzej-UX303LB ~/temp $ tree . . ├── main.py └── packages ├── file.py └── file.pyc 1 directory, 5 files 

Содержание main.py:

 import packages.file as p p.fun() 

и содержимое файла file.py:

 import sys def fun(): print(sys.path) 

Когда я выполняю main.py с Python 2.7.12, я получаю ImportError а выполнение main.py с Python 3.5.2 просто работает.

После добавления __init__.py в каталог пакетов код работает с обеими версиями Python.

Файлы с именем __init__.py используются для маркировки каталогов на диске в виде каталогов пакетов Python. Если у вас есть файлы

 modules/hello/__init__.py modules/hello/module.py 

и modules находятся на вашем пути, вы можете импортировать код в module.py как

 import spam.module 

или

 from spam import module 

Если вы удалите файл __init__.py , Python больше не будет искать подмодули внутри этого каталога, поэтому попытки импортировать модуль не удастся.

Файл __init__.py обычно пуст, но может использоваться для экспорта выбранных частей пакета под более удобным именем, удержания функций удобства и т. Д. Учитывая пример выше, к содержимому модуля init можно получить доступ с помощью

 import spam 

И, наконец, вот что официальная документация должна сказать об этом файле:

Файлы __init__.py необходимы, чтобы Python рассматривал каталоги как содержащие пакеты; это делается для предотвращения каталогов с общим именем, например строки, из непреднамеренного скрытия допустимых модулей, которые появляются позже на пути поиска модуля. В простейшем случае __init__.py может быть просто пустым файлом, но он также может выполнять код инициализации для пакета или задавать переменную __all__ , описанную ниже.

Я думаю, что это хороший «ответ» за то, что я не понял.

 myMath/ __init__.py adv/ __init__.py sqrt.py fib.py add.py subtract.py multiply.py divide.py 

MyMath / __ init__.py

 from add import add from divide import division from multiply import multiply from subtract import subtract from adv.fib import fibonacci from adv.sqrt import squareroot 

index.py

 import sys sys.path.append('C:\Users\mdriscoll\Documents') import mymath print mymath.add(4,5) print mymath.division(4, 2) print mymath.multiply(10, 5) print mymath.fibonacci(8) print mymath.squareroot(48) 

На основании этой ссылки: С Python 3.3

Разрешение неявных пакетов пространства имен означает, что требование предоставить файл init .py можно полностью отбросить

  • Numpy: исправить массив с строками разной длины, заполнив пустые элементы нулями
  • таблица ветряных мельниц с использованием вложенной петли
  • Как вызвать функцию в запущенном потоке Python
  • Получение бесконечного цикла в серии фибоначчи в Python
  • Установка пакета в Python
  • Элементы словаря, не работающие при передаче команды powershell
  • Проблемы с вызовом «on click event» на странице html с использованием красивого супа в Python
  • Более простой способ включения подробного ведения журнала
  • Python - лучший язык программирования в мире.