Почему импорт модуля python не импортирует вложенные модули?

Если я это сделаю:

import lxml 

в python, lxml.html не импортируется. Например, я не могу вызвать функцию lxml.html.parse(). Почему это так?

Ответ 1

Импорт модуля или пакета в Python - это концептуально простая операция:

  • Найдите файл .py, соответствующий импорту. Это включает в себя путь Python и некоторые другие механизмы, но приведет к обнаружению определенного файла .py.

  • Для каждого уровня каталога в импорте (import foo.bar.baz имеет два уровня) найдите соответствующий файл __init__.py и выполните его. Выполнение этого просто означает запуск всех операторов верхнего уровня в файле.

  • Наконец, сам файл .py(foo/bar/baz.py), что означает выполнение всех операторов верхнего уровня. Все глобальные переменные, созданные в результате этого выполнения, объединяются в объект модуля, и этот объект модуля является результатом импорта.

Если ни один из этих шагов не импортирует подпакеты, эти подпакеты недоступны. Если они импортируют подпакеты, они доступны. Авторы пакетов могут делать все, что пожелают.

Ответ 2

lxml называется package в Python, который является иерархическим набором модулей. Пакеты могут быть огромными, поэтому им разрешено избирательно выбирать то, что втягивается, когда они импортируются. В противном случае всем пришлось бы импортировать полную иерархию, что было бы довольно пустой тратой ресурсов.

Ответ 3

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

Ответ 4

lxml - это пакет, а не модуль. Пакет представляет собой набор модулей. Как это бывает, вы также можете импортировать пакет напрямую, но это не автоматически импортирует все его подмодули.

Почему это, ну, это вопрос для BDFL. Я думаю, это вероятно потому, что пакеты, как правило, довольно большие, и импорт всех подмодулей будет чрезмерным снижением производительности.

Ответ 5

Это означает, что нужно загружать только минимальный объем кода для многочастных библиотек, которые вы не можете использовать полностью. Например, вы не можете использовать html часть lxml и, следовательно, не хотите иметь дело с загрузкой его кода.