Вопрос: Для чего __init__.py?


Что __init__.pyдля исходного каталога Python?


1364


источник


Ответы:


Это часть пакета. Вот документация.

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


951



Файлы, названные __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

основанный на это


583



Помимо маркировки каталога как пакета Python и определения __all__, __init__.pyпозволяет вам определить любую переменную на уровне пакета. Это часто бывает удобно, если пакет определяет что-то, что будет импортироваться часто, в стиле API. Эта закономерность способствует соблюдению философии «плоской лучше, чем вложенной».

Пример

Вот пример из одного из моих проектов, в котором я часто импортирую sessionmakerназывается Sessionдля взаимодействия с моей базой данных. Я написал пакет «база данных» с несколькими модулями:

database/
    __init__.py
    schema.py
    insertions.py
    queries.py

мой __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файлы должны быть очень тонкими, чтобы не нарушать «явную, а не скрытую» философию.


361



Существует две основные причины __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
    

    без знания файла1, например

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

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

99



__init__.pyфайл Python обрабатывает каталоги, содержащие его как модули.

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


83



Поскольку 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?


44



In Python the definition of package is very simple. Like Java the hierarchical structure and the directory structure are the same. But you have to have __init__.py in a package. I will explain the __init__.py file with the example below:

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 can be empty, as long as it exists. It indicates that the directory should be regarded as a package. Of course, __init__.py can also set the appropriate content.

If we add a function in module_n1:

def function_X():
    print "function_X in module_n1"
    return

After running:

>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()

function_X in module_n1 

Then we followed the hierarchy package and called module_n1 the function. We can use __init__.py in subPackage_b like this:

__all__ = ['module_n2', 'module_n3']

After running:

>>>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

Hence using * importing, module package is subject to __init__.py content.


43



__init__.py will treat the directory it is in as a loadable module.

For people who prefer reading code, I put Two-Bit Alchemist's comment here.

$ 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
>>> 

35



What is __init__.py used for?

The primary use of __init__.py is to initialize Python packages. The easiest way to demonstrate this is to take a look at the structure of a standard Python module.

package/
    __init__.py
    file.py
    file2.py
    file3.py
    subpackage/
        __init__.py
        submodule1.py
        submodule2.py

As you can see in the structure above the inclusion of the __init__.py file in a directory indicates to the Python interpreter that the directory should be treated like a Python package

What goes in __init__.py?

__init__.py can be an empty file but it is often used to perform setup needed for the package(import things, load things into path, etc).

One common thing to do in your __init__.py is to import selected Classes, functions, etc into the package level so they can be convieniently imported from the package.

In example above we can say that file.py has the Class File. So without anything in our __init__.py you would import with this syntax:

from package.file import File

However you can import File into your __init__.py to make it available at the package level:

# in your __init__.py
from file import File

# now import File from package
from package import File

Another thing to do is at the package level make subpackages/modules available with the __all__ variable. When the interpeter sees an __all__ variable defined in an __init__.py it imports the modules listed in the __all__ variable when you do:

from package import *

__all__ is a list containing the names of modules that you want to be imported with import * so looking at our above example again if we wanted to import the submodules in subpackage the __all__ variable in subpackage/__init__.py would be:

__all__ = ['submodule1', 'submodule2']

With the __all__ variable populated like that, when you perform

from subpackage import *

it would import submodule1 and submodule2.

As you can see __init__.py can be very useful besides its primary function of indicating that a directory is a module.

Reference


26



It facilitates importing other python files. When you placed this file in a directory (say stuff)containing other py files, then you can do something like import stuff.other.

root\
    stuff\
         other.py

    morestuff\
         another.py

Without this __init__.py inside the directory stuff, you couldn't import other.py, because Python doesn't know where the source code for stuff is and unable to recognize it as a package.


25