Import a.b также импортирует?

Когда я импортирую подпакет в пакете, могу ли я полагаться на тот факт, что родительский пакет также импортирован?

например. это работает

python -c "import os.path; print os.getcwd()"

Должен ли я явно import os для os.getcwd быть доступным?

Ответ 1

Там важно знать о пакетах, то есть есть разница между загрузкой и доступностью.

С import a вы загружаете модуль a (который может быть пакетом) и сделать его доступным под именем a.

С from a import b вы загружаете модуль a (который определенно является пакетом), затем загружайте модуль a.b и делайте только это доступным под именем b. Обратите внимание, что a также загружен в процесс, поэтому любая инициализация, которая должна выполняться, будет выполнена.

С помощью import a.b вы загружаете оба и делаете оба доступными (под именами a и a.b).

Ответ 2

Это хороший вопрос. Если вы посмотрите на исходный код для os.py, вы найдете эту строку:

sys.modules['os.path'] = path

Итак, наш модуль. Но что path? Ну, это зависит от вашей ОС. Для Windows он определен в этом блоке:

elif 'nt' in _names:
    name = 'nt'
    linesep = '\r\n'
    from nt import *
    try:
        from nt import _exit
    except ImportError:
        pass
    import ntpath as path

    import nt
    __all__.extend(_get_exports_list(nt))
    del nt

В принципе, os.path является особенным в этом контексте.

Краткая версия: Python делает некоторые вещи за кулисами, чтобы сделать os.path. Вы, вероятно, не должны полагаться на него, чтобы получить другие модули. "Явный лучше, чем неявный" - это то, как идет дзэн.

Ответ 3

Он работает и надежен. Что происходит под капотом, когда вы делаете

import os.path

затем os импортируется, а затем os.path.

Ответ 4

Да, вы можете полагаться на это, всегда работая. Python должен включать os в пространство имен для os.path для работы.

Что не работает, используйте нотацию from os import path. В этом случае модуль os не вводится в пространство имен, а только path.