Используйте 'модуль импорта' или 'от импорта модуля'?

Вот:

_.map(data.stats, obj => [ obj.points, obj.pos ])

Редактировать: @ Хасан Имам сделал интересный ответ, используя разрушающий объект

366
задан Filip Dupanović 20 May 2018 в 19:54
поделиться

9 ответов

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

import module

  • Профессионалы:
    • Меньше обслуживания Вашего import операторы. Не должен добавлять никакой дополнительный импорт, чтобы начать использовать другой объект от модуля
  • Недостатки:
    • Ввод module.foo в Вашем коде может быть утомительным и избыточным (скука может быть минимизирована при помощи import module as mo затем ввод mo.foo)

from module import foo

  • Профессионалы:
    • Меньше ввода для использования foo
    • Больше управления, по которому можно получить доступ к объектам модуля
  • Недостатки:
    • Для использования нового объекта от модуля, необходимо обновить Ваш import оператор
    • Вы теряете контекст о foo. Например, это менее ясно что ceil() делает по сравнению с math.ceil()

Любой метод приемлем, но не использовать from module import *.

Для любого разумного большого набора кода, если Вы import * Вы будете, вероятно, цементировать его в модуль, не могущий быть удаленным. Это вызвано тем, что трудно определить, какие объекты, используемые в коде, прибывают из 'модуля', помогая перейти к сути дела, где Вы думаете, что не используете import больше, но чрезвычайно трудно быть уверенным.

426
ответ дан NullUserException 23 November 2019 в 00:08
поделиться

Оба пути поддерживаются по причине: существуют времена, когда каждый является более соответствующим, чем другой.

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

  • from module import ...: хороший, который импортировал объекты, применимы непосредственно без префикса имени модуля. Недостаток состоит в том, что необходимо перечислить каждую вещь, которую Вы используете, и что не ясно в коде, куда что-то прибыло из.

То, чтобы использовать, зависит, на котором ясно дает понять код и читаемый, и имеет больше, чем немного, чтобы сделать с персональным предпочтением. Я склоняюсь import module обычно, потому что в коде очень ясно, куда объект или функция прибыли из. Я использую from module import ... когда я использую некоторый объект/функцию много в коде.

39
ответ дан dr01 23 November 2019 в 00:08
поделиться

Я лично всегда использую

from package.subpackage.subsubpackage import module

и затем получите доступ ко всему как

module.function
module.modulevar

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

Само собой разумеется, не используйте импорт *, потому что он загрязняет Ваше пространство имен, и он не говорит Вам, куда заданная функция прибывает из (от который модуль)

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

from package1.subpackage import module
from package2.subpackage import module

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

34
ответ дан Stefano Borini 23 November 2019 в 00:08
поделиться
import module

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

from module import function

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

15
ответ дан Andrew Hare 23 November 2019 в 00:08
поделиться

Добавить к тому, о чем сказали люди from x import *: помимо создания его более трудный сказать, куда названия произошли от, это отбрасывает средства проверки кода как Pylint. Они сообщат о тех именах как о неопределенных переменных.

4
ответ дан DNS 23 November 2019 в 00:08
поделиться

Мой собственный ответ на это зависит главным образом от первого, сколько различных модулей я буду использовать. Если я только соберусь использовать один или два, то я буду часто использовать from ... import так как это делает для меньшего количества нажатий клавиш в остальной части файла, но если я собираюсь использовать много различных модулей, я предпочитаю просто import потому что это означает, что каждая ссылка на модули самодокументирует. Я вижу, куда каждый символ прибывает, извне имея необходимость искать вокруг.

Usuaully, который я предпочитаю сам документирование стиля простого импорта и только изменяюсь на от.. импортируйте, когда количество раз, я должен ввести имя модуля, растет выше 10 - 20, даже если существует только один импортируемый модуль.

3
ответ дан SingleNegationElimination 23 November 2019 в 00:08
поделиться

Есть несколько встроенных модулей, которые содержат в основном голые функции ( base64 , math , os , shutil , sys). , time , ...) и это определенно хорошая практика, когда эти голые функции привязывают к некоторому пространству имен и, таким образом, улучшают читабельность вашего кода. Подумайте, насколько труднее понять значение этих функций без их пространства имен:

copysign(foo, bar)
monotonic()
copystat(foo, bar)

, чем когда они связаны с каким-либо модулем:

math.copysign(foo, bar)
time.monotonic()
shutil.copystat(foo, bar)

Иногда вам даже нужно пространство имен для избегать конфликтов между различными модулями ( json.load и pickle.load )


С другой стороны, есть некоторые модули, которые в основном содержат классы ( configparser) , datetime , tempfile , zipfile , ...), и многие из них делают свои имена классов достаточно понятными:
configparser.RawConfigParser()
datetime.DateTime()
email.message.EmailMessage()
tempfile.NamedTemporaryFile()
zipfile.ZipFile()

поэтому может возникнуть спор о том, добавляет ли использование этих классов дополнительное пространство имен модуля в ваш код, добавляет некоторую новую информацию или просто удлиняет код.

0
ответ дан 23 November 2019 в 00:08
поделиться

Одна из значительной разницы, которую я узнал, о котором удивительно никто не говорил, - то, что использование плоскости импорт можно получить доступ private variable и private functions от импортированного модуля, который не возможен с от импорта оператор.

enter image description here

Код в изображении:

setting.py

public_variable = 42
_private_variable = 141
def public_function():
    print("I'm a public function! yay!")
def _private_function():
    print("Ain't nobody accessing me from another module...usually")

plain_importer.py

import settings
print (settings._private_variable)
print (settings.public_variable)
settings.public_function()
settings._private_function()

# Prints:
# 141
# 42
# I'm a public function! yay!
# Ain't nobody accessing me from another module...usually

from_importer.py

from settings import *
#print (_private_variable) #doesn't work
print (public_variable)
public_function()
#_private_function()   #doesn't work
1
ответ дан 23 November 2019 в 00:08
поделиться

Я хотел бы добавить к этому, существуют somethings для рассмотрения во время вызовов импорта:

у меня есть следующая структура:

mod/
    __init__.py
    main.py
    a.py
    b.py
    c.py
    d.py

main.py:

import mod.a
import mod.b as b
from mod import c
import d

dis.dis показывает различие:

  1           0 LOAD_CONST               0 (-1)
              3 LOAD_CONST               1 (None)
              6 IMPORT_NAME              0 (mod.a)
              9 STORE_NAME               1 (mod)

  2          12 LOAD_CONST               0 (-1)
             15 LOAD_CONST               1 (None)
             18 IMPORT_NAME              2 (b)
             21 STORE_NAME               2 (b)

  3          24 LOAD_CONST               0 (-1)
             27 LOAD_CONST               2 (('c',))
             30 IMPORT_NAME              1 (mod)
             33 IMPORT_FROM              3 (c)
             36 STORE_NAME               3 (c)
             39 POP_TOP

  4          40 LOAD_CONST               0 (-1)
             43 LOAD_CONST               1 (None)
             46 IMPORT_NAME              4 (mod.d)
             49 LOAD_ATTR                5 (d)
             52 STORE_NAME               5 (d)
             55 LOAD_CONST               1 (None)

В конце они выглядят одинаково (STORE_NAME является результатом в каждом примере), но это стоит отметить, необходимо ли рассмотреть следующие четыре кругового импорта:

example1

foo/
   __init__.py
   a.py
   b.py
a.py:
import foo.b 
b.py:
import foo.a
>>> import foo.a
>>>

Это работает

example2

bar/
   __init__.py
   a.py
   b.py
a.py:
import bar.b as b
b.py:
import bar.a as a
>>> import bar.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "bar\a.py", line 1, in <module>
    import bar.b as b
  File "bar\b.py", line 1, in <module>
    import bar.a as a
AttributeError: 'module' object has no attribute 'a'

Провал

example3

baz/
   __init__.py
   a.py
   b.py
a.py:
from baz import b
b.py:
from baz import a
>>> import baz.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "baz\a.py", line 1, in <module>
    from baz import b
  File "baz\b.py", line 1, in <module>
    from baz import a
ImportError: cannot import name a

, Подобной проблемой..., но ясно от y импорта x не является то же как импорт импорта x.y как y

example4

qux/
   __init__.py
   a.py
   b.py
a.py:
import b 
b.py:
import a
>>> import qux.a
>>>

, Этот также работает

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

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