Импорт Python *
Мне обычно говорили, что это плохая практика.
from module import *
Основная причина (или, как мне сказали), заключается в том, что вы можете импортировать то, что вам не нужно, и оно может затенять аналогичную именованную функцию или класс из другого модуля.
Однако, что относительно PyQt
from PyQt4.QtCore import *
Каждый пример, который я когда-либо видел, написан таким образом, главным образом потому, что все, что экспортируется из Qt, начинается с "Q", поэтому он не собирается ничего скрывать.
Что такое консенсус? Всегда ли использовать * импорт?
EDIT:
Чтобы быть понятным, этот вопрос особенно касается использования PyQt4. Это не имеет никакого отношения к тому, как я разрабатываю какой-то другой проект.
В принципе, я обнаружил, что кодирование PEP8 улучшило мою читаемость кода, кроме как в отношении импорта PyQt4, и поэтому я до сих пор игнорировал хмуры от пуристов. Но теперь моя группа разработчиков принимает решение по одному соглашению, и мне интересно, является ли это сценарием "где практичность превосходит чистоту", или если я просто буду всасывать его и иметь дело с чудовищными импортами PyQt4
from PyQt4.QtGui import QComboBox, QLineEdit, QLayout, Q;lakdfaf.......
Ответы
Ответ 1
Это может превратиться в религиозную войну. Это вопрос того, хотите ли вы быть явным или хотите ли вы быть слишком многословным. В общем, следуя Zen of Python, лучше быть явным, но иногда люди просто не считают это практичным перечислять каждый импорт из определенного модуль.
Ответ 2
Мое общее правило заключается в том, что если я не написал модуль, я не импортирую его все. Мой самый большой страх на самом деле заключается в написании локальных переменных, которые могли быть определены в импортированном модуле. Поэтому, чтобы не печатать длинные имена модулей, я использую функцию импорта как функцию. Используя ваш модуль в качестве примера, я бы сделал следующее:
import PyQt4.QtCore as qt
Как говорится, у меня есть много модулей поддержки, которые я пишу, что я буду импортировать все. Как и модуль pyqt, я называю их описательным именем, которое помогает показать, из какого модуля он пришел.
Изменить за комментарий
Когда я использую import *, мои модули поддержки не содержат классов или ничего, что может создать новый экземпляр. Они, как правило, представляют собой группы функций, которые изменяют только существующие экземпляры. Чтобы пояснить мое мнение: если я являюсь владельцем исходного кода, и я буду основным сопровождающим, я буду использовать импорт * в противном случае я бы использовал импорт как.
Еще одна причина, по которой я использую функцию импорта как функцию, - позволить мне имитировать модули для целей отладки. В проекте, над которым я сейчас работаю, я использую pyVisa для разговора с несколькими устройствами GPIB. Когда я не подключен к сети GPIB устройств, я могу использовать модуль dummy_visa для записи на stdout (чтобы проверить, что я отправляю правильный формат) и вернуть случайное число (для проверки моего приложения). См. Ниже
if visa_debug:
import dummy_visa as visa
else:
import visa
gpib = visa.Instrument("GPIB0::10")
gpib.write("MEAS:VOLT?")
Ответ 3
Явное исключение для модулей, которые уже содержат пространство имен в их соглашении об именах (например, Q*
PyQT), вполне разумно. Тем не менее, я рекомендую быть ясным, что по умолчанию все еще "не используют его" и просто перечислите это исключение в своих правилах кодирования.
import *
также приемлемо, когда он используется как трюк манипуляции пространства имен в приложении (две формы, с которыми я знаком, - это дополнительные модули ускорения C, которые импортируются в конце чистой версии Python, и "сглаживание" пространства имен пакетов в __init__
). Ключевым моментом является то, что импортирующий модуль и импортируемый модуль находятся под контролем одного и того же набора разработчиков, и, следовательно, устранение конфликтов пространства имен полностью находится под их контролем.
Последнее исключение для удобства в интерактивном приглашении.
В других ситуациях лучше либо импортировать конкретные имена, либо ссылаться на них косвенно через имя модуля (или, если есть некоторые общие ссылочные позиции, выполните оба варианта:
import module # Можно получить доступ ко всему из модуля import a, b, С# Но мы часто ссылаемся на них, поэтому возвращаем их напрямую
Ответ 4
Учебное пособие, глава 6:
Обратите внимание, что в целом практика импорта * из модуля или пакета неодобрилась, так как часто вызывает плохо читаемый код. Тем не менее, это нормально использовать для сохранения ввода в интерактивные сеансы.
Учебник, глава 10:
Обязательно используйте стиль импорта os вместо импорта os *. Это заставит os.open() скрывать встроенную функцию open(), которая работает по-разному.
Поэтому кажется, что это определенно плохая идея; не самая лучшая идея большую часть времени; и приемлемый ярлык в тех случаях, когда вы хотите набрать меньше, например, в интерактивных сеансах.
Ответ 5
Я нахожу, что import *
получает злоупотребление и может стать головной болью обслуживания, поэтому я избегаю этого для этого и других причин, которые вы заявляете. Тем не менее, я считаю, что это нормально для коротких интерактивных сессий, например. from pylab import *
.
В производственном коде для таких пакетов, как PyQt4.QtCore
, где вы планируете использовать многие из символов, я бы использовал один из следующих синтаксисов, которые делают его явным, в каком пространстве имен используются символы:
from PyQt4 import QtCore
# explicit where the symbol came from
QtCore.QTime()
import PyQt4.QtCore as QT
# less desirable since you need to look in the header to find out what QT is
# but I still prefer it to import *
QT.QTime()
Ответ 6
В общем случае, если вы собираетесь использовать from X import Y
, вам следует четко указать, что вы импортируете. Это не только потому, что это безопаснее, но и потому, что он делает ваш код более читаемым (а обновления к сторонним модулям, которые вы используете, не будут иметь такого же потенциала, чтобы случайно сломать ваш код).
В некоторых примерах кода, демонстрирующих большие пакеты, такие как Qt или matplotlib, примеры будут использовать from module import *
, потому что они часто импортируются только из одного модуля и сохраняют ввод текста и позволяют их примерному коду добраться до точки. Нет причин, по которым вы не можете сделать это в своем коде, но, по крайней мере, использовать его в модерации, особенно если он в больших исходных файлах или других людей будет смотреть на ваш код.
Ответ 7
Дизайн PyQt - это вода под мостом. Я не уверен, что это лучшая вещь, но на нее, вероятно, повлиял подход Qt. AFAIK, Qt не использовал пространства имен С++ исторически (я не уверен, что он их использует сейчас), и поэтому пришлось использовать префиксы. Но все эти проектные решения, вероятно, произошли более 10 лет назад, и это не должно влиять на ваши проектные решения.
Я знаю, что если бы я сейчас разрабатывал библиотеку, я бы определенно решил использовать пространства имен пакетов (которые вы явно импортируете на Python) поверх префиксов. Скажем, мой префикс Pfx - если пользователю библиотеки не нужно писать PfxFunc()
каждый раз, когда ему нужна функция, он, конечно, не заботится о дополнительном символе в Pfx.Func()
, особенно когда он может использовать импорт с определенным символом имена, чтобы сократить это еще больше.
Ответ 8
Рассмотрим этот случай
from foo import *
from bar import *
x=baz()
Теперь предположим, что foo
имеет функцию, называемую baz()
, которую мы используем в нашем коде, и все работает нормально. Проходят месяцы или годы, автор bar
добавляет функцию под названием baz()
. Кто-то обновляет бинго ангела - у нас есть потенциально трудно обнаружить ошибку в программе.
Не говоря уже о том, что просто глядя на эти три строки кода, я не могу сказать, откуда приходит baz
, и не смотря на foo
и bar
Единственный раз, когда я использовал import *
, был бы в интерпретаторе, чтобы сохранить некоторую типизацию