Python Объяснение заявлений об импорте - PullRequest
1 голос
/ 25 мая 2020

Я немного смущен тем, что делают операторы импорта в python, поэтому, чтобы понять, что у меня есть этот образец сценария test.py: следующая команда: python3 test.py Я получаю следующее:

t1
t1 
a1 
m1 
a1 
m1

Было бы здорово, если бы кто-нибудь объяснил мне, почему я получаю следующий результат и что именно происходит.

Ответы [ 2 ]

3 голосов
/ 25 мая 2020

Процесс выполнения немного сложно понять. Но вот это

Когда вы выполняете свой файл с помощью python3 test.py, он выполняет скрипт, первая строка которого генерирует t1

Теперь он вызывает functionA (), который импортирует ваш скрипт ( так что выполнение вашего скрипта второй раз ), который дает t1, затем вызывает functionA () снова , но на этот раз тест уже импортирован , поэтому следующая строка выполнения будет a1. затем мы выполняем строку 3, которая дает m1. Теперь мы выходим за пределы функций (первый вызов) функции A () и выполняем a1

и , затем выходим из первого вызова функции A () и напечатайте m1

Для получения дополнительной информации см. ссылка

0 голосов
/ 26 мая 2020

TL; DR: import загружает каждый модуль только один раз за сеанс интерпретатора. Однако основной модуль отличается тем, что его можно импортировать в двух вариантах.


Оператор import отвечает за две вещи:

  • загрузка целевого модуля в интерпретатор и
  • связывание модуля или его имени в текущей области.

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

Вот почему рекурсивный импорт модуля не приводит к бесконечному повторному запуску его кода.


Главный модуль, т.е. начальный запуск модуля отличается тем, что он может регулярно существовать в двух вариантах:

  • с именем __main__, устанавливается автоматически при запуске модуля, и
  • со своим собственным имя, такое как test, устанавливается автоматически при импорте модуля.

Примечательно, что эти две версии не идентичны. Каждый модуль с защитой if __name__ == "__main__": запускает другой код и, таким образом, достигает другого состояния.

Вот почему модуль __main__ может быть загружен дважды, один раз под именем __main__ и один раз под собственным именем.


Для этого кода в спецификации c последовательность выглядит так:

  • Выполнение python3 test.py устанавливает test.py для импорта как __main__.
  • Модуля __main__ пока нет. Python выполняет test.py для создания модуля.
    • functionA и functionB определены,
    • print("t1") вызывается ,
    • functionA вызывается,
      • import test запущено,
        • Модуля test пока нет. Python выполняет test.py для создания модуля.
          • functionA и functionB определены,
          • print("t1") вызывается ,
          • functionA вызывается,
          • import test запущен,
            • Модуль test уже существует (хотя и не полностью).
            • Python связывает модуль test с именем test.
          • print("a1") называется ,
        • print("m1") называется ,
      • print("a1") называется ,
    • print("m1") называется ,
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...