Рекомендуется не использовать import *
в Python.
Может кто-нибудь, пожалуйста, поделитесь причиной этого, чтобы я мог избежать этого в следующий раз?
python
python-import
Программное обеспечение Энтузиаст
источник
источник
import *
не работает для меня в первую очередь в Python 2 или 3.Ответы:
Потому что он помещает много вещей в ваше пространство имен (может скрыть какой-то другой объект из предыдущего импорта, и вы не будете знать об этом).
Потому что вы не знаете точно, что импортируется, и не можете легко найти, из какого модуля была импортирована определенная вещь (удобочитаемость).
Потому что вы не можете использовать классные инструменты, такие как
pyflakes
статическое обнаружение ошибок в вашем коде.источник
numpy.any
тенями,any
когда они это делаютfrom numpy import *
или «полезный» инструмент делает это для них.import *
делает порядок изimport
заявлений значительных ... даже для стандартных модулей библиотеки , которые обычно не заботятся о порядке ввоза , Нечто столь же невинное, как алфавитизация вашихimport
заявлений, может сломать ваш сценарий, когда бывшая жертва войны за импорт станет единственным выжившим. (Даже если ваш сценарий работает сейчас и никогда не изменяется, он может неожиданно завершиться ошибкой спустя некоторое время, если импортированный модуль вводит новое имя, которое заменяет имя, на которое вы полагались.)Согласно дзен питона :
... не могу с этим поспорить, конечно?
источник
use strict
(JavaScriptvar
). Кроме того, конечно, Python не является типизированным (на самом деле он строго типизирован). В любом случае, даже если вы были правы, это все равно будет противоречить дзен Python, приведенному в этом ответе.Вы не проходите
**locals()
к функциям, не так ли?Поскольку Python отсутствует оператор «включить», и
self
параметр является явным, и Scoping правила довольно просты, это, как правило , очень легко указать пальцем на переменную и сказать , где этот объект приходит от - без чтения других модулей и без каких - либо IDE (которые в любом случае ограничены в способе самоанализа, потому что язык очень динамичен).import *
перерывах все это.Кроме того, он имеет конкретную возможность скрывать ошибки.
Теперь, если в модуле bar есть какие-либо атрибуты "
os
", "mystuff
" и т. Д. ..., они переопределят явно импортированные и, возможно, укажут на совершенно разные вещи. Определение__all__
в строке часто целесообразно - здесь указывается, что будет импортироваться неявно, - но все же сложно отследить, откуда берутся объекты, не читая и не анализируя модуль бара и не следуя его импорту. Сетьimport *
- это первое, что я исправляю, когда беру на себя ответственность за проект.Не поймите меня неправильно: если бы
import *
не хватало, я бы заплакал, чтобы получить это. Но это должно быть использовано осторожно. Хорошим вариантом использования является предоставление интерфейса фасада поверх другого модуля. Аналогично, использование операторов условного импорта или импорта внутри пространств имен функций / классов требует некоторой дисциплины.Я думаю, что в средних и больших проектах, или небольших, с несколькими участниками, требуется минимум гигиены с точки зрения статического анализа - запуск по крайней мере pyflakes или даже лучше правильно настроенного pylint - чтобы поймать несколько видов ошибок до они случаются.
Конечно, поскольку это python - не стесняйтесь нарушать правила и исследовать - но будьте осторожны с проектами, которые могут вырасти в десять раз, если в исходном коде отсутствует дисциплина, это будет проблемой.
источник
execfile()
. К счастью, он редко используется и пропал в 3.x.**vars()
включения глобальных переменных, если вызываемая функция находится в другом файле? : PЭто нормально делать
from ... import *
в интерактивном сеансе.источник
doctest
строки? Вimport *
этом случае интерпретируется ли «песочница»? Спасибо.Это потому, что вы загрязняете пространство имен. Вы импортируете все функции и классы в собственное пространство имен, которое может конфликтовать с функциями, которые вы определяете сами.
Кроме того, я думаю, что использование квалифицированного имени более понятно для задачи обслуживания; Вы видите в самой строке кода, откуда взялась функция, так что вы можете гораздо проще просматривать документы.
В модуле foo:
В вашем коде:
источник
http://docs.python.org/tutorial/modules.html
источник
Скажем, у вас есть следующий код в модуле с именем foo:
и тогда в вашем собственном модуле у вас есть:
Теперь у вас есть трудный для отладки модуль, который выглядит так, как будто в нем есть этри из lxml, но на самом деле вместо него есть ElementTree.
источник
Это все хорошие ответы. Я собираюсь добавить, что при обучении новых людей программировать на Python, имея дело с
import *
очень сложно. Даже если вы или они не написали код, это все равно камень преткновения.Я учу детей (около 8 лет) программировать на Python, чтобы манипулировать Minecraft. Мне нравится давать им полезную среду программирования для работы с ( Atom Editor ) и обучать разработке на основе REPL (через bpython ). В Atom я обнаружил, что подсказки / дополнения работают так же эффективно, как bpython. К счастью, в отличие от некоторых других инструментов статистического анализа, Atom не одурачен
import *
.Однако, давайте возьмем этот пример ... В этой обертке они
from local_module import *
связывают модули, включая этот список блоков . Давайте проигнорируем риск коллизий пространства имен. Делая это,from mcpi.block import *
они превращают весь этот список непонятных типов блоков в то, что вам нужно посмотреть, чтобы узнать, что доступно. Если бы они вместо этого использовалиfrom mcpi import block
, то вы могли бы напечатать,walls = block.
а затем появится список автозаполнения.источник
Понял действительные баллы, которые люди ставят здесь. Однако у меня есть один аргумент, что иногда «импорт звезд» не всегда является плохой практикой:
const.py
:import const
, то для каждой константы я должен ссылаться на нееconst.SOMETHING
, что, вероятно, не самый удобный способ.from const import SOMETHING_A, SOMETHING_B ...
, то, очевидно, это слишком многословно и побеждает цель структурирования.from const import *
лучше сделать выбор.источник
Это очень плохая практика по двум причинам:
Для пункта 1 : Давайте посмотрим пример этого:
Здесь нет, видя код никто не будет получить представление о от того, какой модуль
b
,c
иd
на самом деле принадлежит.С другой стороны, если вы делаете это так:
Это намного чище для вас, и у нового человека, присоединившегося к вашей команде, будет лучшее представление.
Для пункта 2 : пусть говорят оба
module1
иmodule2
имеют переменную какb
. Когда я делаю:Здесь значение из
module1
теряется. Будет трудно отладить, почему код не работает, даже еслиb
он объявлен,module1
и я написал код, ожидающий использования моего кодаmodule1.b
Если у вас есть одни и те же переменные в разных модулях, и вы не хотите импортировать весь модуль, вы можете даже сделать:
источник
В качестве теста я создал модуль test.py с 2 функциями A и B, которые соответственно выдают «A 1» и «B 1». После импорта test.py с помощью:
, , , Я могу запустить две функции как test.A () и test.B (), и «test» отображается как модуль в пространстве имен, поэтому, если я отредактирую test.py, я могу перезагрузить его с помощью:
Но если я сделаю следующее:
нет ссылки на «тест» в пространстве имен, поэтому нет способа перезагрузить его после редактирования (насколько я могу судить), что является проблемой в интерактивном сеансе. Принимая во внимание одно из следующего:
добавит «test» или «tt» (соответственно) в качестве имен модулей в пространство имен, что позволит перезагрузить.
Если я сделаю:
имена «A» и «B» отображаются в пространстве имен как функции . Если я отредактирую test.py и повторю приведенную выше команду, измененные версии функций не будут перезагружены.
И следующая команда вызывает сообщение об ошибке.
Если кто-то знает, как перезагрузить модуль, загруженный "из модуля импорта *", пожалуйста, напишите. В противном случае это будет еще одна причина, чтобы избежать формы:
источник
Как предлагается в документах, вы (почти) никогда не должны использовать
import *
в производственном коде.Хотя импорт
*
из модуля плох, импорт * из пакета еще хуже. По умолчаниюfrom package import *
импортирует любые имена, определенные пакетом__init__.py
, включая любые подмодули пакета, которые были загружены предыдущимиimport
операторами.Однако, если
__init__.py
код пакета определяет именованный список__all__
, он считается списком имен подмодулей, которые следует импортировать приfrom package import *
обнаружении.Рассмотрим этот пример (при условии, что он не
__all__
определен вsound/effects/__init__.py
):Последнее утверждение будет импортировать
echo
иsurround
модули в текущее пространство имен (возможно перекрывая предыдущие определения) , поскольку они определены вsound.effects
пакете , когдаimport
выполняются утверждение.источник