У меня есть два связанных вопроса 'об импорте' Python. Они являются легко тестируемыми, но я хочу ответы, которые определяются языком и не определенные для реализации, и я также интересуюсь стилем/конвенцией, таким образом, я спрашиваю здесь вместо этого.
1)
Если модуль модуль импорта B и модуль B модуль импорта C, может кодировать в модуле ссылочный модуль C без явного импорта? Если так, я корректен в предположении, что это - плохая практика?
2)
Если я импортирую модуль A.B.C, который импортирует модули A и A.B также? Если так, это условно лучше к явно import A; import A.B; import A.B.C
?
Первое, что вам следует знать, это то, что язык Python НЕ является стандартом ISO. Это сильно отличается от C / C ++ и означает, что не существует «правильного» способа определения языкового поведения - CPython может что-то делать только потому, что он был закодирован таким образом, а Jython может сделать наоборот.
о на ваши вопросы, помните, что «импорт» модуля состоит из двух частей: сначала загружается модуль - если он никогда не был, например, если он не был доступен в sys.modules, то имя привязывается к этому модулю в локальное пространство имен.
отсюда:
1) Да, вы можете ссылаться на все, что хотите, из модуля a, указав правильное пространство имен, например, вам нужно будет сделать что-то вроде
BCname = "something"
И я думаю, что это очень редко делается в программах на Python и может считаться плохой практикой, так как это вызывает «переходную зависимость» - если какая-то реализация модуля B подвергается рефакторингу и больше не зависит от C, она должна продолжать предлагать Модуль C только для удовлетворения требований A.
Конечно, установка __ all __ может предотвратить это, и хорошей практикой может быть размещение __ all __ во всех ваших модулях и экспорт только нужных вам символов быть действительно публичным.
2) Да и нет. Выполнение
import a.b.c.d
выполняет первую фазу импорта (загрузка) для всех модулей, а вторая - только для a (и, рекурсивно, для b относительно c и т. Д.), Но все модули в цепочке должны ссылаться на полное пространство имен; после такого импорта вы можете сделать
a.something
a.b.something
a.b.c.something
, но можете ' t do
c.something
b.something
Я должен признать, что такое использование тоже довольно редко; Я обычно предпочитаю способ импорта "из модуля импортировать что-то", и обычно вы просто спрашиваете, что вам нужно - такое вложение не является обычным в библиотеках, и его использование не является таким распространенным.
Часто бывает " внешние пакеты ", просто используемые для организации, которые содержат модули с классами. Очень вероятно, что a, b, c выше - это просто пакеты, а d - это модуль, который действительно содержит классы, функции и другие объекты. Таким образом, правильное использование будет таким:
from a.b.c.d import name1, name2, name3
Надеюсь, это удовлетворило ваше любопытство.
просто используется для организации, которая содержит модули с классами. Очень вероятно, что a, b, c выше - это просто пакеты, а d - это модуль, который действительно содержит классы, функции и другие объекты. Таким образом, правильное использование будет следующим:from a.b.c.d import name1, name2, name3
Надеюсь, это удовлетворило ваше любопытство.
просто используется для организации, которая содержит модули с классами. Очень вероятно, что a, b, c выше - это просто пакеты, а d - это модуль, который действительно содержит классы, функции и другие объекты. Таким образом, правильное использование будет таким:from a.b.c.d import name1, name2, name3
Надеюсь, это удовлетворило ваше любопытство.
Alan's given a great answer, but I wanted to add that for your question 1 it depends on what you mean by 'imports'.
If you use the from C import x
syntax, then x
becomes available in the namespace of B
. If in A
you then do import B
, you will have access to x
from A
as B.x
.
It's not so much bad practice as potentially confusing, and will make debugging etc harder as you won't necessarily know where the objects have come from.