Вопрос-Ответ

What is __init__.py for?

Для чего нужен __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

Этот ответ основан на этой веб-странице.

Ответ 3

В дополнение к маркировке каталога как пакета Python и определению __all__, __init__.py позволяет определять любую переменную на уровне пакета. Часто это удобно, если пакет определяет что-то, что будет часто импортироваться, способом, подобным API. Этот шаблон способствует соблюдению философии Pythonic "плоское лучше вложенного".

Пример

Вот пример из одного из моих проектов, в который я часто импортирую sessionmaker called 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 здесь, я могу начать новый сеанс, используя приведенный ниже синтаксис. Этот код будет таким же, выполняемым изнутри или снаружи каталога пакета "database".

from database import Session
session = Session()

Конечно, это небольшое удобство - альтернативой было бы определить Session в новом файле типа "create_session.py" в моем пакете базы данных и начинать новые сеансы с помощью:

from database.create_session import Session
session = Session()

Читать далее

На reddit есть довольно интересная ветка, посвященная соответствующему использованию __init__.py здесь:

http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/

Похоже, большинство придерживается мнения, что __init__.py файлы должны быть очень тонкими, чтобы не нарушать философию "явное лучше неявного".

Ответ 4

Есть 2 основные причины для __init__.py


  1. Для удобства: другим пользователям не нужно будет знать точное расположение ваших функций в иерархии пакетов (документация).


    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


  2. Если вы хотите, чтобы что-то было инициализировано; например, ведение журнала (которое должно быть помещено на верхний уровень):


     import logging.config
    logging.config.dictConfig(Your_logging_config)


python