То, что import
делает в bar.py
, устанавливает идентификатор с именем i
в пространстве имен модуля bar.py
, который указывает на тот же адрес, что и идентификатор с именем i
в пространстве имен модуля foo.py
.
Это важное различие ... bar.i
указывает не на foo.i
, а на то же пространство в памяти, где хранится объект 10
, на который foo.i
указывает одновременно , В python имена переменных не являются пространством памяти ... они являются идентификатором, указывающим на пространство памяти. При импорте в bar вы настраиваете локальный идентификатор пространства имен.
Ваш код ведет себя как ожидалось до тех пор, пока не будет вызван foo.fi()
, когда идентификатор i
в пространстве имен foo.py изменяется так, чтобы указывать на литерал 99, который является объектом в памяти, очевидно, в другом месте, чем 10. Теперь для пространства имен уровня модуля для foo
есть i
, идентифицирующий объект в памяти, отличный от идентификатора i
в bar.py.
У Шейна и Росфабриканта есть хорошие предложения о том, как настроить ваши модули для достижения того, чего вы хотите.