Подтвердить что ты не робот

Оптимальные методы импорта Python (и Django)

Из различных способов импорта кода существуют ли какие-то способы, которые предпочтительнее использовать, по сравнению с другими? Эта ссылка http://effbot.org/zone/import-confusion.htm вкратце что

from foo.bar import MyClass

не является предпочтительным способом импорта MyClass при нормальных обстоятельствах или если вы не знаете, что делаете. (Скорее, лучший способ:

import foo.bar as foobaralias

а затем в коде для доступа к MyClass используйте

foobaralias.MyClass

)

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

Однако эта статья, с которой я связан, действительно старая.

Я также слышал, что лучше, по крайней мере в контексте проектов Django, вместо этого импортировать только классы, которые вы хотите использовать, а не весь модуль. Было сказано, что эта форма помогает избежать круговых ошибок импорта или, по крайней мере, делает систему импорта django менее хрупкой. Было указано, что собственный код Django, похоже, предпочитает "от x import y" над "import x".

Предполагая, что проект, над которым я работаю, не использует каких-либо специальных функций __init__.py... (все наши файлы __init__.py пустые), какой метод импорта я должен использовать, и почему?

4b9b3361

Ответ 1

Для меня это зависит от ситуации. Если это уникальный метод/класс (т.е. Не process() или что-то в этом роде), и вы собираетесь использовать его много, а затем сохраните ввод и просто выполните from foo import MyClass.

Если вы импортируете несколько элементов из одного модуля, вероятно, лучше просто импортировать модуль и сделать module.bar, module.foo, module.baz и т.д., чтобы сохранить пространство имен в чистоте.

Вы также сказали

Было сказано, что эта форма помогает избежать круговых ошибок импорта или, по крайней мере, делает систему импорта django менее хрупкой. Было указано, что собственный код Django, похоже, предпочитает "от x import y" над "import x".

Я не вижу, как так или иначе можно было бы предотвратить циклический импорт. Причина в том, что даже если вы делаете from x import y, все из x импортируется. В текущее пространство имен вводится только y, но обрабатывается весь модуль x. Попробуйте этот пример:

В test.py введите следующее:

def a():
    print "a"

print "hi"

def b():
    print "b"

print "bye"

Затем в 'runme.py' поставьте:

from test import b

b()

Тогда просто python runme.py

Вы увидите следующий вывод:

hi
bye
b

Итак, все в test.py было запущено, хотя вы импортировали только b

Ответ 2

Во-первых, и первичное правило импорта: никогда не используйте from foo import *.

В статье обсуждается проблема циклического импорта, которая до сих пор существует в плохо структурированном коде. Мне не нравится циклический импорт; их присутствие является сильным признаком того, что какой-то модуль делает слишком много, и его нужно разделить. Если по какой-либо причине вам нужно работать с кодом с циклическим импортом, который нельзя переустановить, import foo является единственным вариантом.

В большинстве случаев разница между import foo и from foo import MyClass невелика. Я предпочитаю второе, потому что там меньше набирается текст, но есть несколько причин, по которым я мог бы использовать первый:

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

    • Хорошо: import myapp.utils as utils; utils.frobnicate()
    • Хорошо: import myapp.utils as U; U.frobnicate()
    • Плохо: from myapp.utils import frobnicate
  • Вы импортируете множество значений из одного модуля. Сохраните пальцы и глаза читателя.

    • Плохо: from myapp.utils import frobnicate, foo, bar, baz, MyClass, SomeOtherClass, # yada yada

Ответ 3

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