Почему “импорт *” плохо?

Этому рекомендуют не использовать import * в Python.

Кто-либо может совместно использовать причину этого, так, чтобы я мог избежать его делающий в следующий раз?

135
задан the Tin Man 20 April 2016 в 17:59
поделиться

7 ответов

  • Потому что он помещает много вещей в ваше пространство имен (может затенять какой-то другой объект из предыдущего импорта, и вы не будете знать об этом).

  • Потому что вы не знаете, что именно импортируется, и не можете легко найти, из какого модуля была импортирована та или иная вещь (читабельность).

  • Потому что вы не можете использовать крутые инструменты вроде pyflakes для статического обнаружения ошибок в вашем коде.

202
ответ дан 23 November 2019 в 23:43
поделиться

Согласно Дзен Python :

Явное лучше, чем неявное.

... не могу ли с этим поспорить?

44
ответ дан 23 November 2019 в 23:43
поделиться

Предположим, у вас есть следующий код в модуле с именем foo:

import ElementTree as etree

, а затем в вашем собственном модуле:

from lxml import etree
from foo import *

Теперь у вас есть трудный для отладки модуль, который выглядит как он В нем есть lxml etree, но на самом деле вместо него есть ElementTree.

8
ответ дан 23 November 2019 в 23:43
поделиться

Можно делать from ... import * в интерактивной сессии.

15
ответ дан 23 November 2019 в 23:43
поделиться

Это потому, что вы загрязняете пространство имен. Вы импортируете все функции и классы из своего пространства имен, которые могут конфликтовать с функциями, которые вы определяете сами.

Кроме того, я думаю, что использование квалифицированного имени более понятно для задачи сопровождения; вы видите в самой строке кода, откуда взялась функция, поэтому вам легче проверить документацию.

В модуле foo:

def myFunc():
    print 1

В вашем коде:

from foo import *

def doThis():
    myFunc() # Which myFunc is called?

def myFunc():
    print 2
16
ответ дан 23 November 2019 в 23:43
поделиться

http://docs.python.org/tutorial/modules.html

Обратите внимание, что в целом практика импорта * из модуля или пакета не одобряется, поскольку это часто приводит к плохо читаемому коду.

10
ответ дан 23 November 2019 в 23:43
поделиться

Вы же не передаете **locals() функциям?

Поскольку в Python нет оператора "include", и параметр self является явным, и правила скопирования довольно просты, обычно очень легко указать пальцем на переменную и сказать, откуда взялся этот объект - без чтения других модулей и без какой-либо IDE (которые все равно ограничены в способах интроспекции из-за того, что язык очень динамичен).

Импорт import * ломает все это.

Кроме того, он имеет конкретную возможность скрыть ошибки.

import os, sys, foo, sqlalchemy, mystuff
from bar import *

Теперь, если модуль bar имеет какие-либо атрибуты "os", "mystuff" и т.д..., они будут переопределять явно импортированные и, возможно, указывать на совсем другие вещи. Определение __all__ в bar часто является разумным - это указывает, что будет импортировано неявно - но все равно трудно проследить, откуда берутся объекты, не читая и не разбирая модуль bar и не следуя его импортам. Сеть import * - это первое, что я исправляю, когда принимаю на себя ответственность за проект.

Не поймите меня неправильно: если бы import * отсутствовал, я бы плакал, чтобы его получить. Но его нужно использовать осторожно. Хорошим примером использования является предоставление фасадного интерфейса над другим модулем. Аналогично, использование условных операторов импорта или импорта внутри пространств имен функций/классов требует некоторой дисциплины.

Я думаю, что в средних и больших проектах, или в небольших проектах с несколькими участниками, необходим минимум гигиены в плане статического анализа - запуск по крайней мере pyflakes или даже лучше правильно настроенного pylint - чтобы отловить несколько видов ошибок до того, как они произойдут.

Конечно, поскольку это python - не стесняйтесь нарушать правила, и исследовать - но опасайтесь проектов, которые могут вырасти в десять раз, если исходный код не соответствует дисциплине, это будет проблемой.

38
ответ дан 23 November 2019 в 23:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: