Рекомендуется не использовать import *
в Python.
Может кто-нибудь, пожалуйста, поделитесь причиной этого, чтобы я мог избежать этого в следующий раз?
import *
не работает для меня в первую очередь в Python 2 или 3.
Рекомендуется не использовать import *
в Python.
Может кто-нибудь, пожалуйста, поделитесь причиной этого, чтобы я мог избежать этого в следующий раз?
import *
не работает для меня в первую очередь в Python 2 или 3.
Ответы:
Потому что он помещает много вещей в ваше пространство имен (может скрыть какой-то другой объект из предыдущего импорта, и вы не будете знать об этом).
Потому что вы не знаете точно, что импортируется, и не можете легко найти, из какого модуля была импортирована определенная вещь (удобочитаемость).
Потому что вы не можете использовать классные инструменты, такие как pyflakes
статическое обнаружение ошибок в вашем коде.
numpy.any
тенями, any
когда они это делают from numpy import *
или «полезный» инструмент делает это для них.
import *
делает порядок из import
заявлений значительных ... даже для стандартных модулей библиотеки , которые обычно не заботятся о порядке ввоза , Нечто столь же невинное, как алфавитизация ваших import
заявлений, может сломать ваш сценарий, когда бывшая жертва войны за импорт станет единственным выжившим. (Даже если ваш сценарий работает сейчас и никогда не изменяется, он может неожиданно завершиться ошибкой спустя некоторое время, если импортированный модуль вводит новое имя, которое заменяет имя, на которое вы полагались.)
use strict
(JavaScript var
). Кроме того, конечно, Python не является типизированным (на самом деле он строго типизирован). В любом случае, даже если вы были правы, это все равно будет противоречить дзен Python, приведенному в этом ответе.
Вы не проходите **locals()
к функциям, не так ли?
Поскольку Python отсутствует оператор «включить», иself
параметр является явным, и Scoping правила довольно просты, это, как правило , очень легко указать пальцем на переменную и сказать , где этот объект приходит от - без чтения других модулей и без каких - либо IDE (которые в любом случае ограничены в способе самоанализа, потому что язык очень динамичен).
import *
перерывах все это.
Кроме того, он имеет конкретную возможность скрывать ошибки.
import os, sys, foo, sqlalchemy, mystuff
from bar import *
Теперь, если в модуле bar есть какие-либо атрибуты " os
", " mystuff
" и т. Д. ..., они переопределят явно импортированные и, возможно, укажут на совершенно разные вещи. Определение __all__
в строке часто целесообразно - здесь указывается, что будет импортироваться неявно, - но все же сложно отследить, откуда берутся объекты, не читая и не анализируя модуль бара и не следуя его импорту. Сетьimport *
- это первое, что я исправляю, когда беру на себя ответственность за проект.
Не поймите меня неправильно: если бы import *
не хватало, я бы заплакал, чтобы получить это. Но это должно быть использовано осторожно. Хорошим вариантом использования является предоставление интерфейса фасада поверх другого модуля. Аналогично, использование операторов условного импорта или импорта внутри пространств имен функций / классов требует некоторой дисциплины.
Я думаю, что в средних и больших проектах, или небольших, с несколькими участниками, требуется минимум гигиены с точки зрения статического анализа - запуск по крайней мере pyflakes или даже лучше правильно настроенного pylint - чтобы поймать несколько видов ошибок до они случаются.
Конечно, поскольку это python - не стесняйтесь нарушать правила и исследовать - но будьте осторожны с проектами, которые могут вырасти в десять раз, если в исходном коде отсутствует дисциплина, это будет проблемой.
execfile()
. К счастью, он редко используется и пропал в 3.x.
**vars()
включения глобальных переменных, если вызываемая функция находится в другом файле? : P
Это потому, что вы загрязняете пространство имен. Вы импортируете все функции и классы в собственное пространство имен, которое может конфликтовать с функциями, которые вы определяете сами.
Кроме того, я думаю, что использование квалифицированного имени более понятно для задачи обслуживания; Вы видите в самой строке кода, откуда взялась функция, так что вы можете гораздо проще просматривать документы.
В модуле foo:
def myFunc():
print 1
В вашем коде:
from foo import *
def doThis():
myFunc() # Which myFunc is called?
def myFunc():
print 2
http://docs.python.org/tutorial/modules.html
Обратите внимание, что в целом практика импорта
*
из модуля или пакета не одобряется, так как это часто вызывает плохо читаемый код .
Скажем, у вас есть следующий код в модуле с именем foo:
import ElementTree as etree
и тогда в вашем собственном модуле у вас есть:
from lxml import etree
from foo import *
Теперь у вас есть трудный для отладки модуль, который выглядит так, как будто в нем есть этри из 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 : Давайте посмотрим пример этого:
from module1 import *
from module2 import *
from module3 import *
a = b + c - d
Здесь нет, видя код никто не будет получить представление о от того, какой модуль b
, c
иd
на самом деле принадлежит.
С другой стороны, если вы делаете это так:
# v v will know that these are from module1
from module1 import b, c # way 1
import module2 # way 2
a = b + c - module2.d
# ^ will know it is from module2
Это намного чище для вас, и у нового человека, присоединившегося к вашей команде, будет лучшее представление.
Для пункта 2 : пусть говорят оба module1
и module2
имеют переменную как b
. Когда я делаю:
from module1 import *
from module2 import *
print b # will print the value from module2
Здесь значение из module1
теряется. Будет трудно отладить, почему код не работает, даже если b
он объявлен, module1
и я написал код, ожидающий использования моего кодаmodule1.b
Если у вас есть одни и те же переменные в разных модулях, и вы не хотите импортировать весь модуль, вы можете даже сделать:
from module1 import b as mod1b
from module2 import b as mod2b
В качестве теста я создал модуль test.py с 2 функциями A и B, которые соответственно выдают «A 1» и «B 1». После импорта test.py с помощью:
import test
, , , Я могу запустить две функции как test.A () и test.B (), и «test» отображается как модуль в пространстве имен, поэтому, если я отредактирую test.py, я могу перезагрузить его с помощью:
import importlib
importlib.reload(test)
Но если я сделаю следующее:
from test import *
нет ссылки на «тест» в пространстве имен, поэтому нет способа перезагрузить его после редактирования (насколько я могу судить), что является проблемой в интерактивном сеансе. Принимая во внимание одно из следующего:
import test
import test as tt
добавит «test» или «tt» (соответственно) в качестве имен модулей в пространство имен, что позволит перезагрузить.
Если я сделаю:
from test import *
имена «A» и «B» отображаются в пространстве имен как функции . Если я отредактирую test.py и повторю приведенную выше команду, измененные версии функций не будут перезагружены.
И следующая команда вызывает сообщение об ошибке.
importlib.reload(test) # Error - name 'test' is not defined
Если кто-то знает, как перезагрузить модуль, загруженный "из модуля импорта *", пожалуйста, напишите. В противном случае это будет еще одна причина, чтобы избежать формы:
from module import *
Как предлагается в документах, вы (почти) никогда не должны использовать import *
в производственном коде.
Хотя импорт *
из модуля плох, импорт * из пакета еще хуже. По умолчанию from package import *
импортирует любые имена, определенные пакетом __init__.py
, включая любые подмодули пакета, которые были загружены предыдущими import
операторами.
Однако, если __init__.py
код пакета определяет именованный список __all__
, он считается списком имен подмодулей, которые следует импортировать при from package import *
обнаружении.
Рассмотрим этот пример (при условии, что он не __all__
определен в sound/effects/__init__.py
):
# anywhere in the code before import *
import sound.effects.echo
import sound.effects.surround
# in your module
from sound.effects import *
Последнее утверждение будет импортировать echo
и surround
модули в текущее пространство имен (возможно перекрывая предыдущие определения) , поскольку они определены в sound.effects
пакете , когда import
выполняются утверждение.