Ответ 1
Да, ваши наблюдения верны. Это является следствием того, как связывание работает в Python.
Когда вы делаете
import foo
тогда foo
становится глобальным именем, которое ссылается на модуль foo
. Когда вы делаете
foo.bar = 7
Затем выполняется ссылка и загружается объект foo
. Затем 7
сохраняется в атрибуте bar
.
Когда другой модуль импортирует foo
, он просто вытаскивает объект из sys.modules['foo']
и получает измененное значение.
Когда вы делаете
from foo import bar
globals()['bar']
устанавливается в качестве ссылки foo.bar
. Когда один из них делает
bar = 7
globals()['bar']
больше не ссылается на foo.bar
, а ссылается на копию 7
. То есть первоначальная привязка в глобальной области модуля импорта просто заменяется.
В первом примере один из них модифицирует атрибуты объекта, который хранится в sys.modules
, и будет общим для всех модулей, которые его импортировали. Во втором примере изменяется глобальная область модуля импорта.
Если бы кто-то делал что-то по строкам
from foo import fobaz
fobaz.foobar = 7
Затем это изменение будет распространено на другие модули импорта, потому что одно не переписывает глобальную ссылку, а следует за ней, чтобы изменить атрибут объекта, на который он указывает. По существу, вы должны иметь возможность изменять изменяемые объекты, пока вы не перезаписываете глобальную привязку.
Я думаю, что что-то вроде этого самое близкое, что вы сможете полностью перейти к истинному глобальному в python. В качестве языка он значительно присваивает пространствам имен.