На любом лексическом уровне from amodule import *
- это проектное решение «казалось хорошей идеей в то время», которое оказалось настоящей катастрофой в реальной жизни, за исключением возможного удобного исследования в интерактивном режиме.подсказка интерпретатора (даже в этом случае я не слишком разбираюсь в этом - import module as m
заставляет использовать только два дополнительных символа вместо полных имен [[просто префикс m.
]], и полные именавсегда острее и более гибким, чем голые имена, не говоря уже о большой пользе в исследовательских интерактивных ситуациях наличия m
для help(m)
, reload(m)
и т. п.!).
Эта потрепанная конструкция делает егоочень трудно, чтобы бедный человек, читающий код (часто в обреченной попытке помочь отладить его), понять, откуда появляются загадочные имена - невозможно, если конструкция используется более одного раза на лексическом уровне;но даже когда он используется только один раз, он вызывает кропотливое перечитывание всего модуля каждый раз, прежде чем можно будет убедить себя в том, что да, что неопрятное голое имя должно исходить от модуля.
Кроме того, авторы модулей обычно нене пойдем на крайнюю неприятность, необходимую для «поддержки» рассматриваемой ужасной конструкции.Если где-то в вашем коде вы, скажем, используете sys.argv
(и, конечно, import sys
в самом верху вашего модуля), как вы знаете , что sys
являетсямодуль должен быть ... или какой-то совершенно другой (или немодульный) из ... import *
?!Умножьте это на все квалифицированные имена, которые вы используете, и страдания - это единственный конечный результат - таинственные ошибки, требующие долгой кропотливой отладки (обычно с неохотной помощью кого-то, кто делает"get")Python ...! -).
Внутри функции способ добавления и переопределения произвольных локальных имен будет еще хуже.В качестве элементарной, но решающей оптимизации компилятор Python просматривает тело функции для любого присваивания или других операторов связывания для каждого голого имени и считает «локальными» те имена, которые он видит таким образом назначенными (остальные должны быть глобальными или встроенными).С import *
(точно так же, как с exec somestring
без явных диктов для использования в качестве пространств имен), внезапно становится полной загадкой, какие имена являются локальными, а какие глобальными - поэтому бедному компилятору придется прибегнуть к медленномувозможная стратегия для каждого поиска имени, используя dict для локальных переменных (вместо компактного «вектора», который он обычно использует) и выполняя до трех поисков dict для каждого голого имени, на которое ссылаются, снова и снова.
Goна любую интерактивную подсказку Python.Тип import this
.Что ты видишь?Дзен Питона.Какая последняя и, вероятно, самая большая мудрость в этом тексте ...?
Пространства имен - это одна из замечательных идей - давайте сделаем еще больше!
Принуждениемиспользование голых имен, в которых квалифицированные имена , так что значительно предпочтительнее, вы, по сути, делаете то же самое против этой мудрой рекомендации: вместо того, чтобы восхищаться величием и сигналом пространства имен, и делать большеиз них вы разбиваете два совершенно хороших и готовых к использованию пространства имен (того из модуля, который вы импортируете, и пространства лексической области, в которое вы его импортируете), чтобы сделатьодиночный, нечестивый, глючный, медленный, жесткий, бесполезный беспорядок.
Если бы я мог вернуться и изменить один раннее решение о дизайне в Python (это трудный выбор, потому что использование def
и особенно lambda
за то, что в Javascript гораздо более читабельно называется function
- это близкая секунда ;-), я бы задним числом уничтожил идею import *
из разума Гвидо.Никакое количество предполагаемого удобства для исследования в интерактивном режиме не может уравновесить количество зла, которое он совершил ...! -)