Рекурсивный импорт в Python
На 27 Django Moscow Meetup Николай Чабановский рассказывал про Stackoverflow на русском.
Написал ответ на вопрос, ответ получился слишком обширным, на правах автора забираю сюда.
Вопрос был про рекурсивный импорт в Python.
recur1.py:
recur2.py:
В ходе импортирования инструкции в файле выполняются сначала и до конца.
Если выполним следующее:
То получим ошибку:
Это происходит по очень простой причине. В модуле recur1 сначала создается переменная x, а потом сразу импортируется recur2, в котором мы используем from.
Таким образом, у нас будет доступ только к тем именам, которые уже были определены в этом модуле. То есть доступ только к x, y не будет доступен, так как к нему будет присвоено значение после импорта в recur1.
Лучше не использовать при рекурсивном импорте инструкцию from. При рекурсивном импорте интерпретатор не будет повторно выполнять инструкции.
Это легко можно проверить:
Ошибки не происходит, потому что при первом импорте мы получаем x, потом снова импортируем из recur1 recur2, повторного определения переменной х происходить не будет (см. выше), поэтому сразу получим y, и когда уже захотим импортнуть его из recur2, также повторно инструкции не будут выполняться.
Идем дальше:
И когда после этого мы захотим сразу сделать:
То ошибки в
не будет, так как y уже будет объявлен в recur1:
Вернет:
Если же запустим
Получим:
Как пишет Лутц:
Когда модули запускаются как самостоятельные программы, они не импортируются, поэтому здесь возникает тот же эффект, как и при импортировании recur2 в интерактивной оболочке, – recur2 является первым импортируемым модулем.
А при
В выводе увидим:
То есть мы еще не объявили в recur1 переменную y, поэтому ее и нет.