В модуле recur1 присваивается имя X и затем перед присваиванием имени Y импортируется модуль recur2. В этой точке recur2 может извлечь recur1 как единое целое с помощью оператора import — он уже существует во внутренней таблице модулей Python, которая делает его импортируемым и также препятствует зацикливанию операций импортирования. Но если в модуле гecuг2 применяется from, то он будет в состоянии видеть только имя X; имя Y, которое присваивается позже оператора import в recur1, еще не существует, а потому вы получите ошибку:
from recur1 import X # Нормально: имя X уже присвоено
from recur1 import Y # Ошибка: имя Y пока не существует
Python избегает повторного выполнения операторов модуля recur1, когда он рекурсивно импортируется из recur2 (иначе операции импортирования отправляли бы сценарий в бесконечный цикл, который мог бы требовать нажатия <Ctrl+C> или чего-то более радикального), но пространство имен модуля recurl является незавершенным, когда он импортируется в модуле recur2.
Если бы в recur2.py использовался просто
import recur1
, а не from recur1 import Y
, всё бы сработало, потому что import не требует, чтобы имя уже было определено — оно просто добавляет модуль как объект:
import recur1
print(recur1.Y) # Это бы сработало, если бы вызвалось после выполнения recur1.py
>>Click here to continue<<