Первое, что вы должны знать, это то, что язык Python НЕ является стандартом ISO. Это несколько отличается от C / C ++, и это означает, что не существует «правильного» способа определения поведения языка - CPython может что-то делать только потому, что он был закодирован таким образом, а Jython может делать наоборот.
о ваших вопросах, помните, что "импорт" модуля - это операция, состоящая из двух частей: сначала модуль загружается - если его никогда не было, например, если он не был доступен в sys.modules, то имя связывается с этим модулем в локальном пространстве имен.
следовательно:
1) Да, вы можете ссылаться на все, что вы хотите от модуля a, предоставляя правильное пространство имен, например, вам придется сделать что-то вроде
B.C.name = "что-то"
И я думаю, что это очень редко делается в программах на Python и может считаться плохой практикой, так как это вызывает «транзитивный переход» - если какая-то реализация модуля B подвергается рефакторингу и больше не зависит от C, она должна продолжать предлагать Модуль C только для удовлетворения Aps.
Конечно, установка __ all __ может предотвратить это, и хорошей практикой может быть помещение __ all __ во все ваши модули и экспорт просто символов, которые вы хотите сделать действительно общедоступными.
2) Да и нет. Doing
import a.b.c.d
выполняет первый этап импорта (загрузка) для всех модулей, но второй только для a (и, рекурсивно, в b относительно c и т. Д.), Но все модули в цепочке должны быть ссылается на полное пространство имен; после такого импорта можно сделать
a.something
a.b.something
a.b.c.something
но вы не можете сделать
c.something
b.something
Я должен признать, что такое использование довольно редко; Обычно я предпочитаю способ импорта из модуля «что-то импортировать», и, как правило, вы просто спрашиваете, что вам нужно - такое вложение не является обычным явлением в библиотеках, и его использование не столь распространено.
Часто бывают «внешние пакеты», просто используемые для организации, которые содержат модули с классами. Весьма вероятно, что a, b, c выше - это просто пакеты, а d - это модуль, который действительно содержит классы, функции и другие объекты. Таким образом, правильное использование будет:
from a.b.c.d import name1, name2, name3
Надеюсь, это утоляет ваше любопытство.