Когда я импортирую подпакет в пакете, могу ли я полагаться на тот факт, что родительский пакет также импортирован?
например. это работает
python -c "import os.path; print os.getcwd()"
Должен ли я явно import os
для os.getcwd
быть доступным?
Когда я импортирую подпакет в пакете, могу ли я полагаться на тот факт, что родительский пакет также импортирован?
например. это работает
python -c "import os.path; print os.getcwd()"
Должен ли я явно import os
для os.getcwd
быть доступным?
Там важно знать о пакетах, то есть есть разница между загрузкой и доступностью.
С import a
вы загружаете модуль a
(который может быть пакетом) и сделать его доступным под именем a
.
С from a import b
вы загружаете модуль a
(который определенно является пакетом), затем загружайте модуль a.b
и делайте только это доступным под именем b
. Обратите внимание, что a
также загружен в процесс, поэтому любая инициализация, которая должна выполняться, будет выполнена.
С помощью import a.b
вы загружаете оба и делаете оба доступными (под именами a
и a.b
).
Это хороший вопрос. Если вы посмотрите на исходный код для 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
. Вы, вероятно, не должны полагаться на него, чтобы получить другие модули. "Явный лучше, чем неявный" - это то, как идет дзэн.
Он работает и надежен. Что происходит под капотом, когда вы делаете
import os.path
затем os
импортируется, а затем os.path
.
Да, вы можете полагаться на это, всегда работая. Python должен включать os
в пространство имен для os.path
для работы.
Что не работает, используйте нотацию from os import path
. В этом случае модуль os не вводится в пространство имен, а только path
.