пакет: избегайте импорта всего модуля при импорте только одного из его членов в __init__.py - PullRequest
0 голосов
/ 14 октября 2019

Извините, если название не очень ясно, но я не суммировал хорошо. Я экспериментирую с пакетами и нахожусь в такой ситуации:

$:~/project$ tree
.
├── first_mod.py
└── first_package
    ├── __init__.py
    └── sub_package
        ├── __init__.py
        └── second_mod.py

В первом __init__.py внутри first_package dir я задаю это содержимое:

from first_package.sub_package.second_mod import function

(очевидно,в модуле second_mod есть функция с именем function)

Если я открою интерпретатор в каталоге project и импортирую first_package, а затем попробую посмотреть, что в нем содержится, с помощью автозаполнения вкладки, вВ дополнение к function также указан sub_package.

>>> import first_package
>>> first_package.                             [tab]
first_package.function(    first_package.sub_package

Вопрос: неизбежно ли, что sub_package также отображается как содержимое first_package, когда я импортирую только function в __init__.py?

1 Ответ

0 голосов
/ 21 октября 2019

Такое поведение можно объяснить кратким изложением того, что происходит, когда вы импортируете модуль baz с оператором, подобным import foo.bar.baz.

1: импорт родительских модулей

Прежде чем baz может быть импортирован, bar должен быть там. И прежде чем bar может быть импортирован, необходимо наличие foo - у python нет способа достичь baz с помощью ярлыка.

2: запуск __init__.py файлов

В каждом пакете, который импортируется до baz, имеется файл __init__.py, который выполняется.

3: загрузка обнаруженных модулей в sys.modules

при импорте папкикак пакет, все файлы Python в нем импортируются как модули (за исключением файлов __init__.py, которые можно представить себе как замену для самого пакета). Они будут загружены в sys.modules и доступны объектам пакета (в данном случае это foo, `` bar , and baz`).


И это в значительной степени так,подробности можно найти здесь .

В вашем примере были выполнены два оператора import (один вами и один при запуске first_package/__init__.py), но только первыйНужно объяснить, что случилось. Когда вы импортировали first_package, третий шаг загружает все модули, которые являются частью пакета. Это включает sub_package, и нет никакого способа обойти это, используя стандартные механизмы импорта.

Выполнение

del first_pacakge.sub_package

удалит его из объекта на тот случай, если вы заботитесь только об этом, но не выгружает его и все равно будет в sys.modules.

...