Как точно работает импорт Python?

У меня есть две конкретные ситуации, когда я не понимаю, как импортирование работает в Python:

1-я конкретная ситуация:

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

2-я конкретная ситуация:

Рассмотрим следующий модуль, который называется bla.py :

 a = 10 

И тогда у нас есть foo.py , модуль, который импортирует bla.py :

 from bla import * def Stuff (): return a 

И после этого у нас есть скрипт bar.py , который запускается пользователем:

 from foo import * Stuff() #This should return 10 a = 5 Stuff() 

Здесь я не знаю: Does Stuff() возвращает 10 или 5?

2 Solutions collect form web for “Как точно работает импорт Python?”

Часть 1

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

Первое место – это sys.modules , кеш всех модулей, которые были импортированы ранее. [ источник ]


Часть 2

from foo import * импортирует a в локальную область. При назначении значения a оно заменяется новым значением, но исходная переменная foo.a не затрагивается.

Поэтому, если вы не import foo и не изменяете foo.a , оба вызова возвращают одно и то же значение.

Для изменяемого типа, такого как список или dict, это будет другим, изменение его действительно повлияет на исходную переменную – но присвоение ему нового значения все равно не foo.whatever .

Если вы хотите получить более подробную информацию, посмотрите http://docs.python.org/reference/executionmodel.html :

Следующие конструкции связывают имена: формальные параметры для функций, операторы импорта , определения классов и функций (они связывают имя класса или функции в определяющем блоке) и целевые объекты, которые являются идентификаторами, если они встречаются в назначении , для заголовка цикла, во втором позиции заголовка блока except или после того, как в инструкции a с.

Два смелых раздела являются для вас релевантными: сначала имя a привязывается к значению foo.a во время импорта. Затем, когда a = 5 , имя a связано с 5 . Поскольку изменение списка / dict не вызывает привязки, эти операции будут изменять исходный ( b и foo.b привязаны к тому же объекту, на котором вы работаете). Присвоение нового объекта b будет снова связыванием и, таким образом, отделить b от foo.b

Также стоит отметить, что именно делает инструкция import :

  • import foo связывает имя модуля с объектом модуля в текущей области, поэтому, если вы изменяете foo.whatever , вы будете работать с именем в этом модуле – любые изменения / назначения будут влиять на переменную в модуле.
  • from foo import bar связывает только указанное имя (т.е. foo будет оставаться несвязанным) с элементом с таким же именем в foo – поэтому операции на bar ведут себя так, как описано ранее.
  • from foo import * ведет себя как предыдущий, но импортирует все глобальные имена, которые не имеют префикса с подчеркиванием. Если модуль определяет __all__ только имена внутри этой последовательности.

Часть 3 (которая даже не существует в вашем вопросе: p)

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

Чтобы ответить на ваш первый вопрос:

Нет, python не получает «импорт» дважды. Когда python загружает модуль, он проверяет модуль в sys.modules . Если его там нет, он помещается туда и загружается.

Чтобы ответить на ваш второй вопрос:

Модули могут определять, какие имена они будут экспортировать в from camelot import * , а поведение – создавать имена для существующих значений, а не ссылаться на существующие переменные (у python нет ссылок).

По некоторой смежной теме, делать from camelot import * не совпадает с регулярным импортом .

  • учебник flaskr; не может импортировать flaskr (инициализировать базу данных)
  • Развернуть путь поиска Python к другому источнику
  • Глобальный импорт внешнего модуля модуля Python
  • модуль не имеет подмодуля
  • Необычные параметры импорта ошибок в django
  • Многоуровневый относительный импорт
  • Импорт __module__ python: почему символы подчеркивания?
  • Python: импорт подпакета или подмодуля
  • Python - лучший язык программирования в мире.