Почему модули Python иногда не импортируют свои подмодули?
Я заметил что-то странное сегодня, которое я хотел бы объяснить. Я не был на 100% уверен, как даже сформулировать это как вопрос, поэтому google не может быть и речи. Модуль регистрации не имеет доступа к модулю logging.handlers по какой-то нечетной причине. Попробуйте сами, если вы мне не верите:
>>> import logging
>>> logging.handlers
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'handlers'
>>> import logging.handlers
>>> logging.handlers
<module 'logging.handlers' from '/usr/lib/python2.6/logging/handlers.pyc'>
Может ли кто-нибудь объяснить, почему это происходит?
Ответы
Ответ 1
В Python модули необходимо импортировать, прежде чем они будут доступны. import logging
импортирует только модуль регистрации. Так получилось, что logging
представляет собой пакет с подмодулями, но эти подмодули по-прежнему не загружаются автоматически. Итак, вам нужно явно импортировать logging.handlers
, прежде чем вы сможете получить к нему доступ.
Если вам интересно, почему это выглядит, иногда вам не нужны эти дополнительные импортные пакеты: некоторые пакеты импортируют некоторые или все их подмодули при импорте - просто делая эти импорт в своих файлах __init__.py
. В других случаях это может быть то, что вы импортируете, а также импортировали logging.handlers
. Не имеет значения, какой фрагмент кода выполняет импорт; пока что-то в вашем процессе импортирует logging.handlers
, прежде чем вы его получите, он будет там. И иногда модуль, который выглядит как пакет, действительно не один, например os
и os.path
. os
не является пакетом, он просто импортирует правильный другой модуль (для вашей платформы) и называет его path
, поэтому вы можете получить к нему доступ как os.path
.
Ответ 2
Я также новичок в Python и, пройдя большую практику, теперь я могу различать: пакет (папка), модуль (.py), классы, переменные... и т. Д...
если вы хотите, чтобы любая ваша папка была пакетом python - она должна содержать файл __init__.py
даже пустой файл подойдет !!!
и, как сказал Томас, вы можете импортировать дополнительный модуль в __init__.p
y, если хотите !!! но модули/пакеты доступны только после его импорта...
если вы хотите импортировать все из модуля, вы можете использовать
from logging import *
остальное вы можете получить доступ к модулю обработчиков, как показано ниже,
from logging import handlers
print dir(handlers)
Ответ 3
В последнее время я столкнулся с той же странной ситуацией. Итак, я уверен, вы удалили импорт сторонних библиотек. Эта удаленная библиотека содержала
from logging import handlers
или from logging import *
и предоставит вам handlers
. А в другом script у вас есть что-то вроде import logging
и просто используется logging.handlers
, и вы подумали, что это так, как я.
Ответ 4
Томас Воутерс очень хорошо ответил на этот вопрос, но, увы, я нашел этот вопрос только после того, как нашел ответ в оригинальной документации. С этой целью я думал, что добавлю к этому в надежде, что это появится ближе к вершине поисковой системы в будущем.
ВОПРОС
Почему появляется ошибка: " AttributeError: module 'имя_модуля" не имеет атрибута "sub_module_name ", хотя мой редактор (например, Visual Code) автоматически заполняет имя подмодуля:
import module_name
module_name.sub_module_name(parameter)
ОТВЕТ
Ваш редактор основывает свое автозаполнение на файловой структуре вашего проекта, а не на поведении Python. Подмодули не импортируются автоматически при импорте модуля. Обратитесь к документации Python для получения подробной информации о том, как "автоматически" импортировать подмодули при использовании
import module_name
Ключевым вкладом этого ответа является добавление AttributeError при попытке импортировать "модуль" или "пакет"
Надеюсь, это поможет кому-то!