Что происходит в Python, когда вы импортируете внутри функции? [Дубликат]

142
задан Michael Currie 7 May 2015 в 15:32
поделиться

6 ответов

Повторно импортируется ли он каждый раз при запуске функции?

Нет; или, скорее, модули Python кэшируются каждый раз при импорте, поэтому импорт второго (или третьего, или четвертого ...) раза на самом деле не заставляет их снова проходить весь процесс импорта. 1

Импортируется ли он один раз в начале, независимо от того, запущена ли функция?

Нет, он импортируется только в том случае, если и когда функция выполняется. 2 , 3

Что касается преимуществ: это зависит, наверное. Если вы можете запускать функцию очень редко и вам не нужно импортировать модуль где-либо еще, может быть выгодным импортировать его только в эту функцию. Или, если есть конфликт имен или другая причина, по которой вы не хотите, чтобы модуль или символы из модуля были доступны повсюду , вы можете импортировать их только в определенной функции. (Конечно, в таких случаях всегда есть from my_module import my_function as f .)

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

129
ответ дан 23 November 2019 в 23:11
поделиться

Самый первый раз, когда вы импортируете goo из любого места (внутри или вне функции), goo.py (или в другой импортируемой форме ) загружается, а sys.modules ['goo'] устанавливается для построенного таким образом объекта модуля. Любой будущий импорт в рамках того же запуска программы (опять же, внутри или вне функции) просто найдите sys.modules ['goo'] и привяжите его к barename goo в соответствующий объем. Поиск dict и привязка имени - очень быстрые операции.

Предполагая, что самый первый импорт в любом случае полностью амортизируется за время выполнения программы, наличие «соответствующей области» на уровне модуля означает каждое использование goo.this , goo.that и т. д. - это два поиска по dict - один для goo , а второй - для имени атрибута. Если он находится на «уровне функции», то при каждом запуске функции оплачивается одна дополнительная настройка локальной переменной (даже быстрее, чем при поиске по словарю!), Но сохраняется один поиск по словарю (замена его на поиск по локальной переменной, невероятно быстро) для каждого goo.this (и т. Д.) Доступ, в основном сокращая вдвое время, необходимое для таких поисков.

Так или иначе, мы говорим о нескольких наносекундах, так что вряд ли это стоящая оптимизация.Одно потенциально существенное преимущество наличия import внутри функции заключается в том, что эта функция может вообще не понадобиться в данном запуске программы, например, эта функция имеет дело с ошибками, аномалиями и редкими ситуациями. В основном; в этом случае любой прогон, которому не нужны функциональные возможности, даже не будет выполнять импорт (и это экономия микросекунд, а не только наносекунд), только запуски, которые действительно нуждаются в функциональности, будут платить (скромную, но измеримую) цену.

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

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

Импортируется один раз при первом выполнении функции.

Плюсы:

  • импорт, связанный с функцией, в которой они используются
  • , легко перемещать функции по пакету

Минусы:

  • не мог видеть, от каких модулей этот модуль может зависеть
10
ответ дан 23 November 2019 в 23:11
поделиться

Могу я в целом предложить вместо вопроса «Сможет ли X улучшить мою производительность?» вы используете профилирование, чтобы определить, где ваша программа на самом деле тратит свое время, а затем применяете оптимизацию в зависимости от того, где вы получите наибольшую выгоду?

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

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

Импортирование внутри функции фактически импортирует модуль один раз... при первом запуске функции.

Он должен импортироваться так же быстро, импортируете ли вы его сверху или при запуске функции. Обычно это не очень хорошая причина для импорта в def. За? Он не будет импортирован, если функция не вызывается. На самом деле это разумная причина, если ваш модуль требует, чтобы у пользователя был установлен определенный модуль, только если он использует определенные ваши функции...

Если вы делаете это не по этой причине, то почти наверняка это плохая идея.

5
ответ дан 23 November 2019 в 23:11
поделиться

Импорт выполняется один раз, когда функция вызывается в первый раз.

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

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

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