'из X импортировать' против 'импорта X; X.a '

Я видел, как некоторые программисты Python довольно последовательно используют следующий стиль (назовем его стилем 1):

import some_module
# Use some_module.some_identifier in various places.

В поддержку этого стиля вы можете процитировать максиму "явное лучше, чем неявное". Я видел, как другие программисты использовали этот стиль (стиль 2):

from some_module import some_identifier
# Use some_identifier in various places.

Основное преимущество, которое я вижу в стиле 2, - это ремонтопригодность - особенно с идеалами утка печатать я могу заменить some_module на some_other_module. Я также чувствую, что стиль 2 приносит очки с максимой "удобочитаемость имеет значение". Хотя я склонен не соглашаться, всегда можно утверждать, что поиск и замена - такой же хороший вариант при использовании первого стиля.

Дополнение: Было отмечено, что вы можете использовать as для переключения с some_module на some_other_module в стиле 1. Я забыл упомянуть, что также часто принято решение о реализации some_identifier в вашем модуле ток, что делает создание эквивалентного контейнера some_module немного неудобным. .

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
9
0
2 847
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

При наличии следующего синтаксиса:

import some_other_module as some_module

аргумент ремонтопригодности стиля 2 больше не актуален.

Я предпочитаю использовать стиль 1. Обычно я обнаруживаю, что в типичной программе Python явно ссылаюсь на имя импортированного пакета всего несколько раз. Все остальное - это методы объекта, которым, конечно, не нужно ссылаться на импортированный пакет.

Я обычно использую порог, чтобы решить это. Если я хочу использовать много чего в some_module, я буду использовать:

import some_module as sm
x = sm.whatever

Если мне понадобится всего одна или две вещи:

from some_module import whatever
x = whatever

Это, конечно, при условии, что мне не нужен whatever от some_other_module.

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

Я верю, что в более новых версиях Python (2.5+? Должны проверить мои факты ...) вы даже можете:

import some_other_module as some_module

Таким образом, вы все равно можете использовать стиль 1 и позже заменить его другим модулем.

Я думаю, это обычно соответствует тому, насколько вы хотите загромождать свое пространство имен. Вы будете использовать в модуле только одно или два имени? Или все они (from x import * не всегда плохой, просто в целом)?

Я считаю, что обозначение

from some_module import some_symbol

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

from some_module import some_symbol as other_symbol

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

import  module [as other_module]

Только в двух случаях:

  1. Я использую слишком много функций / объектов модуля, чтобы импортировать их все
  2. Модуль определяет некоторый символ, который может измениться во время выполнения.

Я предпочитаю import X, а затем по возможности использую X.a.

Мое исключение касается глубоко вложенных модулей в большом фреймворке, таком как Django. Их имена модулей имеют тенденцию становиться длинными, и во всех их примерах указано from django.conf import settings, чтобы вы не набирали django.conf.settings.DEBUG повсюду.

Если имя модуля глубоко вложено, то исключение составляет использование from X.Y.Z import a.

Я лично стараюсь не слишком сильно связываться с моим пространством имен, поэтому в большинстве ситуаций я просто делаю

import module  

или же импортировать модуль как мод

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

from SuperImprovedListOverloadedWithFeatures import NewLIst
nl = NewList()

и т.п.

Ответ принят как подходящий

Оба случая можно использовать, поэтому я не думаю, что это проблема либо-либо. Я бы подумал об использовании модуля import x,y,z, когда:

  • Есть довольно небольшое количество вещей для импорта

  • Назначение импортируемых функций очевидно, если их отделить от имени модуля. Если имена довольно общие, они могут противоречить другим и мало что вам скажут. например. remove мало что вам скажет, но os.remove, вероятно, намекнет, что вы имеете дело с файлами.

  • Имена не совпадают. Аналогично предыдущему, но более важно. Никогда сделать что-то вроде:

     from os import open
    

import module [as renamed_module] имеет то преимущество, что он дает немного больше контекста о том, что вызывается, когда вы его используете. Его недостаток состоит в том, что он немного более загроможден, когда модуль на самом деле не предоставляет больше информации, и немного менее эффективен (2 поиска вместо 1).

Однако он также имеет преимущества при тестировании (например, замена os.open на фиктивный объект, без необходимости изменять каждый модуль), и его следует использовать при использовании изменяемых модулей, например

import config
config.dburl = 'sqlite:///test.db'

Если сомневаетесь, я всегда выбрал бы стиль import module.

Я обычно использую только несколько членов каждого модуля, поэтому есть много

from john import cleese
from terry import jones, gilliam

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

import michael
import sarah

import wave

gov_speech = wave.open(sarah.palin.speechfile)
parrot_sketch = wave.open(michael.palin.justresting)

(Я мог бы использовать from wave import open as wave_open, но полагаю, что wave.open будет более знаком читателю.

Вас может заинтересовать вопрос о переполнении стека Почему «import x; x.y» ведет себя иначе, чем «from x import y», а первый дает сбой, когда пакет x.в этом не завершен?.

Другие вопросы по теме