Для чего __init__.py?
Что такое __init__.py
для исходного каталога Python?
Ответы
Ответ 1
Раньше он был обязательной частью пакета (старый "обычный пакет" до 3.3, а не более новый 3. 3+ "пакет пространства имен").
Здесь документация.
Python определяет два типа пакетов, обычные пакеты и пакеты пространства имен. Обычные пакеты - это традиционные пакеты, которые существовали в Python 3.2 и более ранних версиях. Обычный пакет обычно реализуется как каталог, содержащий файл __init__.py
. Когда импортируется обычный пакет, этот файл __init__.py
выполняется неявно, и определяемые им объекты привязываются к именам в пространстве имен пакетов. Файл __init__.py
может содержать тот же код Python, что и любой другой модуль, и Python добавит некоторые дополнительные атрибуты в модуль при его импорте.
Но просто нажмите на ссылку, она содержит пример, дополнительную информацию и объяснение пакетов пространства имен, типа пакетов без __init__.py
.
Ответ 2
Файлы с именем __init__.py
используются для маркировки каталогов на диске в виде каталогов пакетов Python.
Если у вас есть файлы
mydir/spam/__init__.py
mydir/spam/module.py
и mydir
находится на вашем пути, вы можете импортировать код в module.py
как
import spam.module
или
from spam import module
Если вы удалите файл __init__.py
, Python больше не будет искать подмодули внутри этого каталога, поэтому попытки импортировать модуль не удастся.
Файл __init__.py
обычно пуст, но может использоваться для экспорта выбранных частей пакета под более удобным именем, удержания функций удобства и т.д.
В приведенном выше примере содержимое модуля init можно получить как
import spam
на основе this
Ответ 3
В дополнение к маркировке каталога как пакета Python и определению __all__
, __init__.py
позволяет вам определять любую переменную на уровне пакета.. Это часто удобно, если пакет определяет что-то которые будут импортироваться часто, по API-подобным образом. Эта закономерность способствует соблюдению философии "плоской лучше, чем вложенной" в питоновскую философию.
Пример
Вот пример из одного из моих проектов, в котором я часто импортирую sessionmaker
под названием Session
для взаимодействия с моей базой данных. Я написал пакет "database" с несколькими модулями:
database/
__init__.py
schema.py
insertions.py
queries.py
My __init__.py
содержит следующий код:
import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)
Так как я определяю Session
здесь, я могу начать новый сеанс, используя синтаксис ниже. Этот код был бы таким же выполненным изнутри или вне каталога пакета базы данных.
from database import Session
session = Session()
Конечно, это небольшое удобство - альтернативой было бы определить Session
в новом файле типа "create_session.py" в моем пакете базы данных и начать новые сеансы, используя:
from database.create_session import Session
session = Session()
Дальнейшее чтение
Существует довольно интересная красноватая нить, охватывающая соответствующие применения __init__.py
здесь:
http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
По мнению большинства, файлы __init__.py
должны быть очень тонкими, чтобы не нарушать "явную, лучше неявную" философию.
Ответ 4
Есть две основные причины __init__.py
-
Для удобства: другим пользователям не нужно будет знать точное местоположение ваших функций в иерархии вашего пакета.
your_package/
__init__.py
file1.py
file2.py
...
fileN.py
# in __init__.py
from file1 import *
from file2 import *
...
from fileN import *
# in file1.py
def add():
pass
тогда другие могут вызвать add()
from your_package import add
не зная file1, вроде
from your_package.file1 import add
-
Если вы хотите что-то инициализировать; например, ведение журнала (который следует поместить на верхний уровень):
import logging.config
logging.config.dictConfig(Your_logging_config)
Ответ 5
Файл __init__.py
позволяет каталогам Python обрабатывать их как модули.
Кроме того, это первый файл, который нужно загрузить в модуле, поэтому вы можете использовать его для выполнения кода, который вы хотите запускать каждый раз при загрузке модуля, или указать подмодули, которые будут экспортированы.
Ответ 6
Так как Python 3.3, __init__.py
больше не требуется определять каталоги как импортируемые пакеты Python.
Отметьте PEP 420: Неявные пакеты пространства имен:
Встроенная поддержка каталогов пакетов, для которых не требуются файлы маркеров __init__.py
, и может автоматически охватывать несколько сегментов маршрута (вдохновленные различными сторонними подходами к пакетам пространства имен, как описано в PEP 420)
Здесь тест:
$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
ссылки:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Не требуется ли __init__.py для пакетов в Python 3?
Ответ 7
В Python определение пакета очень просто. Подобно Java, иерархическая структура и структура каталогов одинаковы. Но вы должны иметь __init__.py
в пакете. Я объясню файл __init__.py
следующим примером:
package_x/
|-- __init__.py
|-- subPackage_a/
|------ __init__.py
|------ module_m1.py
|-- subPackage_b/
|------ __init__.py
|------ module_n1.py
|------ module_n2.py
|------ module_n3.py
__init__.py
может быть пустым, если он существует. Он указывает, что каталог следует рассматривать как пакет. Конечно, __init__.py
также может установить соответствующий контент.
Если мы добавим функцию в module_n1:
def function_X():
print "function_X in module_n1"
return
После запуска:
>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()
function_X in module_n1
Затем мы выполнили пакет иерархии и вызвали функцию module_n1. Мы можем использовать __init__.py
в subPackage_b следующим образом:
__all__ = ['module_n2', 'module_n3']
После запуска:
>>>from package_x.subPackage_b import *
>>>module_n1.function_X()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named module_n1
Следовательно, используя * importing, пакет модулей подчиняется __init__.py
контенту.
Ответ 8
Хотя Python работает без файла __init__.py
вы все равно должны включить его.
Он указывает, что пакет должен рассматриваться как модуль, поэтому включайте его (даже если он пуст).
Также есть случай, когда вы можете использовать файл __init__.py
:
Представьте, что у вас была следующая файловая структура:
main_methods
|- methods.py
И methods.py
содержали это:
def foo():
return 'foo'
Для использования foo()
вам понадобится одно из следующих:
from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()
Может быть, вам нужно (или хотят), чтобы держать methods.py
внутри main_methods
(время автономной работы/зависимостей, например), но вы только хотите импортировать main_methods
.
Если вы изменили имя methods.py
на __init__.py
вы можете использовать foo()
, просто импортировав main_methods
:
import main_methods
print(main_methods.foo()) # Prints 'foo'
Это работает, потому что __init__.py
рассматривается как часть пакета.
Некоторые пакеты Python действительно делают это. Примером является JSON, где при запуске import json
фактически импортируется __init__.py
из пакета json
(см. Здесь структуру файла пакета):
Исходный код: Lib/json/__init__.py
Ответ 9
__init__.py
будет обрабатывать каталог, в котором он находится в качестве загружаемого модуля.
Для людей, которые предпочитают читать код, я помещаю комментарий Двубичный алхимик.
$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$
$ rm /tmp/mydir/spam/__init__.py*
$
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>>
Ответ 10
Он облегчает импорт других файлов python. Когда вы помещаете этот файл в каталог (например, материал), содержащий другие файлы py, вы можете сделать что-то вроде import stuff.other.
root\
stuff\
other.py
morestuff\
another.py
Без этого __init__.py
внутри содержимого каталога вы не можете импортировать файл other.py, потому что Python не знает, где исходный код для материала и не может распознать его как пакет.
Ответ 11
Что такое __init__.py, используемый для?
Основное использование __init__.py
- инициализация пакетов Python. Самый простой способ продемонстрировать это - взглянуть на структуру стандартного модуля Python.
package/
__init__.py
file.py
file2.py
file3.py
subpackage/
__init__.py
submodule1.py
submodule2.py
Как вы можете видеть в структуре выше включение файла __init__.py
в каталог указывает интерпретатору Python, что каталог должен рассматриваться как пакет Python
Что происходит в __init__.py
?
__init__.py
может быть пустым файлом, но часто используется для выполнения настройки, необходимой для пакета (импортировать вещи, загружать вещи в путь и т.д.).
В вашем __init__.py
есть одна общая задача: импортировать выбранные классы, функции и т.д. на уровень пакета, чтобы их можно было импортировать из пакета.
В приведенном выше примере мы можем сказать, что file.py имеет файл класса. Таким образом, без чего-либо в нашем __init__.py
вы импортируете этот синтаксис:
from package.file import File
Однако вы можете импортировать File в свой __init__.py
, чтобы сделать его доступным на уровне пакета:
# in your __init__.py
from file import File
# now import File from package
from package import File
Еще одна вещь, которую нужно сделать, это на уровне пакета сделать подпакеты/модули доступными с переменной __all__
. Когда интерпретатор видит переменную __all__
, определенную в __init__.py
, она импортирует модули, перечисленные в переменной __all__
, когда вы делаете:
from package import *
__all__
- это список, содержащий имена модулей, которые вы хотите импортировать с импортом *, так что снова просмотрев наш вышеприведенный пример, если мы хотим импортировать подмодули в подпакет, переменная __all__
в subpackage/__init__.py
будет
__all__ = ['submodule1', 'submodule2']
С переменной __all__
, заполненной таким образом, когда вы выполняете
from subpackage import *
он импортирует подмодуль1 и подмодуль2.
Как вы можете видеть, __init__.py
может быть очень полезен, кроме его основной функции, указывая, что каталог является модулем.
Ссылка
Ответ 12
Файл __init__.py
упрощает импорт. Когда в пакете присутствует __init__.py
, функцию a()
можно импортировать из файла b.py
следующим образом:
from b import a
Без этого, однако, вы не можете импортировать напрямую. Вы должны изменить системный путь:
import sys
sys.path.insert(0, 'path/to/b.py')
from b import a
Ответ 13
Я нашел объяснение в
https://timothybramlett.com/How_to_create_a_Python_Package_with___init__py.html
быть намного понятнее, чем любой из вышеперечисленных. Это также включает пример. Можно прочитать и понять примерно за три минуты.