Оптимизирует ли python модули, когда они импортируются несколько раз? - PullRequest
44 голосов
/ 17 ноября 2008

Если большой модуль загружается каким-то подмодулем вашего кода, есть ли какая-то польза от ссылки на модуль из этого пространства имен вместо его импорта снова?

Например: У меня есть модуль MyLib, который широко использует ReallyBigLib. Если у меня есть код, который импортирует MyLib, я должен выкопать модуль так:

import MyLib
ReallyBigLib = MyLib.SomeModule.ReallyBigLib

или просто

import MyLib
import ReallyBigLib

Ответы [ 6 ]

65 голосов
/ 17 ноября 2008

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

import MyLib
import ReallyBigLib

Соответствующая документация по заявлению на импорт:

https://docs.python.org/2/reference/simple_stmts.html#the-import-statement

Как только имя модуля известно (если не указано иное, термин «модуль» будет относиться как к пакетам, так и к модулям), можно начинать поиск модуля или пакета. Первое место проверено sys.modules, кеш всех модулей, которые были импортированы ранее. Если модуль найден там, он используется на шаге (2) импорта.

Импортированные модули кэшируются в sys.modules :

Это словарь, который отображает имена модулей на модули, которые уже были загружены. Этим можно манипулировать для принудительной перезагрузки модулей и других хитростей. Обратите внимание, что удаление модуля из этого словаря отличается от вызова reload () для соответствующего объекта модуля.

35 голосов
/ 18 ноября 2008

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

Попробуйте этот код:

   # module/file a.py
   print "Hello from a.py!"
   import b

   # module/file b.py
   print "Hello from b.py!"
   import a

Цикла нет: есть только поиск в кэше.

>>> import b
Hello from b.py!
Hello from a.py!
>>> import a
>>>

Одна из прелестей Python - то, как все сводится к выполнению сценария в пространстве имен.

8 голосов
/ 17 ноября 2008

Это не имеет существенного значения. Если большой модуль уже был загружен, второй импорт в вашем втором примере ничего не делает, кроме добавления 'ReallyBigLib' в текущее пространство имен.

6 голосов
/ 05 ноября 2009

ВНИМАНИЕ: Python не гарантирует, что модуль не будет инициализирован дважды. Я столкнулся с такой проблемой. Смотрите обсуждение: http://code.djangoproject.com/ticket/8193

3 голосов
/ 19 ноября 2008

Внутренний реестр импортируемых модулей - это словарь sys.modules, который сопоставляет имена модулей с объектами модулей. Вы можете посмотреть там, чтобы увидеть все модули, которые в настоящее время импортированы.

Вы также можете использовать некоторые полезные приемы (если вам нужно), используя sys.modules - например, добавляя свои собственные объекты в виде псевдомодулей, которые можно импортировать другими модулями.

0 голосов
/ 17 ноября 2008

То же самое по производительности. В Python еще нет JIT-компилятора.

...