Архив метки: __init__.py

Python — Пример импортирования пакета

Рассмотрим практический пример программного кода, который демонстрирует, как используются файлы инициализации и пути к каталогам. Следующие три файла располагаются в каталоге dir1 и в подкаталоге dir2 – комментарии описывают пути к этим файлам:
# Файл: dir1__init__.py
Print(‘dir1 init’)
x = 1

# Файл: dir1dir2__init__.py
Print(‘dir2 init’)
y = 2

# Файл: dir1dir2mod.py
Print(‘in mod.py’)
z = 3
В данном случае каталог dir1 может быть подкаталогом нашего рабочего каталога (то есть домашнего каталога программы) или подкаталогом одного из каталогов, перечисленных в пути поиска модулей (технически, входящего в список sys.path). В любом из этих случаев для каталога, вмещающего подкаталог dir1, не требуется наличие файла __init__.py.
Инструкции  import  выполняют  файлы  инициализации  в  каждом  каталоге, которые присутствуют в пути к модулю, – инструкции print, присутствующие в этих файлах, позволят отследить их выполнение. Кроме того, как и файлы модулей, уже импортированные каталоги могут передаваться функции reload для  принудительного  повторного  исполнения  этого  единственного  элемента.
Как показано ниже, для повторной загрузки каталогов и файлов функция reload также может принимать цепочку имен, разделенных точками:


>>> import dir1.dir2.mod       # Сначала запускаются файлы инициализации
dir1 init
dir2 init
in mod.py
>>>
>>> import dir1.dir2.mod       # Повторное импортирование не выполняется
>>>
>>> from imp import reload     # Требуется в версии 3.0
>>> reload(dir1)
dir1 init

>>>
>>> reload(dir1.dir2)
dir2 init

После операции импортирования путь, указанный в инструкции import, становится цепочкой вложенных объектов. Здесь mod – это объект, вложенный в объект dir2, который в свою очередь вложен в объект dir1:
>>> dir1

>>> dir1.dir2

>>> dir1.dir2.mod

Каждый каталог в пути фактически становится переменной, которой присваивается объект модуля, пространство имен которого инициализируется всеми инструкциями присваивания в файле __init__.py, находящемся в этом каталоге. Имя dir1.x ссылается на переменную x, которой присваивается значение 
в файле dir1__init__.py, точно так же, как имя mod.z ссылается на переменную 
z, которой присваивается значение в файле mod.py:
>>> dir1.x
1

>>> dir1.dir2.y

2
>>> dir1.dir2.mod.z

3

Автор: Няшный Человек
Дата публикации: 2016-03-22T20:30:00.000+02:00

Файлы __init__.py пакетов

Если вы решили использовать импортирование пакетов, существует еще одно условие, которое необходимо будет соблюдать: каждый каталог в пути, указанном в инструкции импортирования пакета, должен содержать файл с именем __init__.py, в противном случае операция импорта пакета будет терпеть неудачу. То есть в примере выше каталоги dir1 и dir2 должны содержать файл с именем __init__.py каталог-контейнер dir0 может не содержать такой файл, потому что сам он не указан в инструкции импортирования пакета. Точнее говоря, для такой структуры каталогов:
dir0dir1dir2mod.py
и инструкции импортирования, имеющей следующий вид:
import dir1.dir2.mod
применяются следующие правила:
•  dir1 и dir2 должны содержать файл __init__.py.
•  dir0, каталог-контейнер, может не содержать файл __init__.py – этот файл
будет проигнорирован, если он присутствует.
•  dir0, но не dir0dir1, должен присутствовать в пути поиска модулей (то есть он  должен  быть  домашним  каталогом  или  присутствовать  в  переменной окружения PYTHONPATH и так далее).

Таким образом, структура каталогов в этом примере должна иметь следующий вид (здесь отступы указывают на вложенность каталогов):

dir0          # Каталог-контейнер в пути поиска модулей
    dir1
        __init__.py
        dir2
            __init__.py
            mod.py
Файлы __init__.py могут содержать программный код на языке Python, как любые другие файлы модулей. Отчасти они являются объявлениями для интерпретатора и могут вообще ничего не содержать. Эти файлы, будучи объявлениями, предотвращают неумышленное сокрытие в каталогах с совпадающими именами истинно требуемых модулей, если они отображаются позже в списке путей поиска модулей. Без этого защитного механизма интерпретатор мог бы выбирать  каталоги,  которые  не  имеют  никакого  отношения  к  вашему  программному коду, только лишь потому, что в пути поиска они появляются ранее.
В общем случае файл __init__.py предназначен для выполнения действий по инициализации пакета, создания пространства имен для каталога и реализации поведения инструкций from * (то есть from … import *), когда они используются для импортирования каталогов:

Инициализация пакета
 Когда интерпретатор Python импортрирует каталог в первый раз он автоматически запускает программный код файла __init__.py этого каталога. По этой причине обычно в эти файлы помещается программный код, выполняющий действия по инициализации, необходимые для файлов в пакете.
 Например, этот файл инициализации в пакете может использоваться для создания файлов с данными, открытия соединения с базой данных и так далее. Обычно файлы __init__.py не предназначены для непосредственного выполнения – они запускаются автоматически, когда выполняется первое обращение к пакету.

Инициализация пространства имен модуля
При импортировании пакетов пути к каталогам в вашем сценарии после завершения операции импортирования превращаются в настоящие иерархии вложенных объектов. Например, в предыдущем примере после завершения операции импортирования можно будет использовать выражение dir1.dir2, которое возвращает объект модуля, чье пространство имен содержит все имена, определяемые файлом __init__.py из каталога dir2. Такие файлы создают пространства имен для объектов модулей, соответствующих каталогам, в которых отсутствуют настоящие файлы модулей.

Поведение инструкции from *
В качестве дополнительной особенности, в файлах __init__.py можно использовать списки __all__, чтобы определить, что будет импортироваться из каталог