Это - pythonic для импорта внутренних функций?

int main() {
    auto call = [](auto a) {
        std::cout << a << std::endl;
    };

    if(i = 0)
        call(myclass1 { "Example1" });
    else 
        call(myclass2 { "Example2" });
}
111
задан codeape 21 June 2009 в 17:08
поделиться

6 ответов

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

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

Еще один момент: я предпочитаю получать исключение ImportError перед запуском любого кода - как проверка работоспособности, так что это еще одна причина для импорта вверху.

Я использую pyChecker для проверки неиспользуемых модулей.

77
ответ дан 24 November 2019 в 03:05
поделиться

В двух случаях я нарушаю PEP 8 в этом отношении:

  • Циклический импорт: модуль A импортирует модуль B, но что-то в модуле B нуждается в модуле A (хотя это часто является признаком что мне нужно провести рефакторинг модулей, чтобы устранить циклическую зависимость)
  • Вставка точки останова pdb: import pdb; pdb.set_trace () Это удобно. Я не хочу помещать import pdb в начало каждого модуля, который я мог бы захотеть отладить, и легко не забыть удалить импорт. когда я удаляю точку останова.

За исключением этих двух случаев, рекомендуется разместить все наверху. Это делает зависимости более понятными.

41
ответ дан 24 November 2019 в 03:05
поделиться

Вот четыре варианта использования импорта, которые мы используем

  1. import from x import y и import x as y ) вверху

  2. Варианты импорта. Вверху.

     настройки импорта
    если настройка. что-то:
     импортировать это как foo
    еще:
     импортировать это как foo
    
  3. Условный импорт. Используется с библиотеками JSON, XML и т. Д. Вверху.

     попробуйте:
     импортировать это как foo
    кроме ImportError:
     импортировать это как foo
    
  4. Динамический импорт. Пока у нас есть только один пример.

     import settings
    module_stuff = {}
    module = __import __ (settings.some_module, module_stuff)
    x = module_stuff ['x']
    

    Обратите внимание, что этот динамический импорт не вносит код, но вносит сложные структуры данных, написанные на Python. Это похоже на маринованный кусок данных за исключением того, что мы мариновали его вручную.

    Это также, более или менее, вверху модуля


Вот что мы делаем, чтобы сделать код более ясным:

  • Делайте модули короткими.

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

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

19
ответ дан 24 November 2019 в 03:05
поделиться

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

Если вы делаете 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
7
ответ дан 24 November 2019 в 03:05
поделиться

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

6
ответ дан 24 November 2019 в 03:05
поделиться

Если это import , а не from x import * , вы должны поместить их вверху. Он добавляет только одно имя к глобальному пространству имен, и вы придерживаетесь PEP 8. Плюс, если оно вам позже понадобится где-то еще, вам не нужно ничего перемещать.

В этом нет ничего страшного, но поскольку там почти нет разница Я бы посоветовал делать то, что говорит PEP 8.

2
ответ дан 24 November 2019 в 03:05
поделиться
Другие вопросы по тегам:

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