Это питон для импорта внутри функций?
PEP 8 говорит:
- импорт всегда помещается в верхней части файла, сразу после любого модуля
комментарии и docstrings, а перед модулем глобалы и константы.
на occation, я нарушаю PEP 8. Несколько раз я импортирую вещи внутри функций. Как правило, я делаю это, если есть импорт, который используется только в одной функции.
какие мнения?
изменить (причина Я чувствую, что импорт в функции может быть хорошей идеей):
основная причина: это может сделать код яснее.
- когда я смотрю на код функции, я могу спросить себя: "Что такое функция/класс xxx?"(xxx используется внутри функции). Если у меня есть все мои импорт в верхней части модуля, я должен пойти посмотреть там, чтобы определить, что такое xxx. Это больше проблема при использовании
from m import xxx. Видяm.xxxв функции, вероятно, говорит мне больше. В зависимости от чегоmis: это хорошо известный модуль/пакет верхнего уровня (import m)? Или это суб-модуль / пакет (from a.b.c import m)? - в некоторых случаях имея эту дополнительную информацию ("что такое xxx?") близко к тому, где используется xxx, может облегчить понимание функции.
7 ответов:
в долгосрочной перспективе я думаю, что вы оцените, что большая часть вашего импорта находится в верхней части файла, таким образом, вы можете сразу сказать, насколько сложен ваш модуль, что ему нужно импортировать.
Если я добавляю новый код в существующий файл, я обычно делаю импорт там, где это необходимо, а затем, если код остается, я сделаю все более постоянным, переместив строку импорта в верхнюю часть файла.
еще один момент, я предпочитаю, чтобы получить
ImportErrorисключение перед любым кодом выполняется -- как проверка здравомыслия, так что это еще одна причина для импорта сверху.Я использую
pyCheckerдля проверки неиспользуемых модулей.
есть два случая, когда я нарушаю PEP 8 в этом отношении:
- циклический импорт: модуль a импортирует модуль B, но что-то в модуле B нуждается в модуле A (хотя это часто признак того, что мне нужно рефакторинг модулей для устранения циклической зависимости)
- вставка точки останова pdb:
import pdb; pdb.set_trace()Это удобно b / c я не хочу ставитьimport pdbв верхней части каждого модуля я мог бы хотеть отлаживать, и это легко запомнить, чтобы удалить импорт, когда я удаляю точка прерывания.за пределами этих двух случаев, это хорошая идея, чтобы положить все на вершине. Это делает зависимости более ясными.
вот четыре варианта использования импорта, которые мы используем
import(иfrom x import yиimport x as y) в верхнейвыбор для импорта. На вершине.
import settings if setting.something: import this as foo else: import that as fooУсловный Импорт. Используется с библиотеками JSON, XML и тому подобное. На вершине.
try: import this as foo except ImportError: import that as fooДинамический Импорт. Пока у нас есть только один пример этого.
import settings module_stuff = {} module= __import__( settings.some_module, module_stuff ) x = module_stuff['x']обратите внимание, что этот динамический импорт не делает вводим код, но вводим сложный структуры данных, написанные на Python. Это вроде как маринованный кусок данных только мы мариновали его вручную.
это тоже, более или менее, в верхней части модуля
вот что мы делаем, чтобы сделать код более понятным:
держите модули короткими.
если у меня есть все мои импорта в верхней части модуля, я должна пойти туда, чтобы выяснить, что зовут. Если модуль короткий, это легко сделать.
в некоторых случаях наличие этой дополнительной информации, близкой к тому, где используется имя, может облегчить понимание функции. Если модуль короткий, это легко сделать.
одна вещь, чтобы иметь в виду: ненужный импорт может вызвать проблемы с производительностью. Так что если это функция, которая будет вызываться часто, лучше всего положить на импорт в верхней части. Конечно, это - это оптимизация, поэтому, если есть допустимый случай, чтобы импорт внутри функции был более ясным, чем импорт в верхней части файла, это в большинстве случаев превосходит производительность.
Если вы делаете IronPython, мне сказали, что лучше импортировать внутренние функции (так как компиляция кода в IronPython может быть медленной). Таким образом, вы можете быть в состоянии получить способ с импортом внутренних функций тогда. Но кроме этого, я бы сказал, что просто не стоит бороться с Конвенцией.
Как правило, я делаю это, если есть импорт, который используется только в одной функции.
еще один момент, который я хотел бы сделать, это то, что это может быть потенциальная проблема обслуживания. Что произойдет, если вы добавите функцию, которая использует модуль, который ранее использовался только одной функцией? Вы собираетесь не забыть добавить импорт в верхнюю часть файла? Или вы собираетесь сканировать каждую функцию для импорта?
FWIW, есть случаи, когда имеет смысл импортировать внутри функции. Например, если вы хотите установить язык в cx_Oracle, вам нужно установить NLS
_переменная окружения LANG до это импортировать. Таким образом, вы можете увидеть такой код:import os oracle = None def InitializeOracle(lang): global oracle os.environ['NLS_LANG'] = lang import cx_Oracle oracle = cx_Oracle
Я нарушил это правило раньше для модулей, которые являются самотестированием. То есть, они обычно просто используются для поддержки, но я определяю основной для них, так что если вы запустите их сами по себе, вы можете проверить их функциональность. В таком случае я иногда импортирую
getoptиcmdпросто в основном, потому что я хочу, чтобы было ясно, что кто-то читает код, что эти модули не имеют ничего общего с нормальной работой модуля и включены только для тестирования.
пока
import, а неfrom x import *, вы должны положить их в верхней части. Он добавляет только одно имя в глобальное пространство имен, и вы придерживаетесь PEP 8. Кроме того, если вам позже понадобится это где-то еще, вам не нужно ничего перемещать.это не имеет большого значения, но так как нет почти никакой разницы, я бы предложил делать то, что говорит PEP 8.
исходя из вопроса о загрузка модуля дважды - почему не оба?
импорт в верхней части скрипта будет указывать на зависимости, а другой импорт в функции делает эту функцию более атомарной, хотя, по-видимому, не вызывает никакого недостатка производительности, поскольку последовательный импорт дешев.
Comments