Python 确认导入*与自xxx导入之间的差异*

Python 确认导入*与自xxx导入之间的差异*,python,python-import,Python,Python Import,我很惊讶地发现这一点 import foo 及 对全球成员有不同的影响。我想确认我的实验是正确的 在第一个示例中,更改模块foo中的成员将反映在导入foo的所有代码中。但是,在后一种情况下更改该成员似乎只会影响导入该成员的文件。换句话说,使用后一种方法将为每个导入文件提供其自己的foo成员副本 我想要的行为是从所有文件访问foo.x,能够从所有文件对其进行更改,并将更改反映在所有文件中(如果愿意的话,请使用真正的全局变量)。考虑到全局变量通常被认为是一件坏事,我怀疑“真正的全局”变量将是一件非

我很惊讶地发现这一点

import foo

对全球成员有不同的影响。我想确认我的实验是正确的

在第一个示例中,更改模块foo中的成员将反映在导入foo的所有代码中。但是,在后一种情况下更改该成员似乎只会影响导入该成员的文件。换句话说,使用后一种方法将为每个导入文件提供其自己的foo成员副本


我想要的行为是从所有文件访问foo.x,能够从所有文件对其进行更改,并将更改反映在所有文件中(如果愿意的话,请使用真正的全局变量)。

考虑到全局变量通常被认为是一件坏事,我怀疑“真正的全局”变量将是一件非常糟糕的事情


获得类似行为的另一种方法是在单例对象中使用类作用域属性,然后导入该属性。这样就更清楚了“全局”变量的来源。

是的,您的观察是正确的。这是Python中绑定工作方式的结果

当一个人

import foo
然后
foo
成为引用模块
foo
的全局名称。当一个人

foo.bar = 7
from foo import bar
然后跟随引用并加载对象
foo
。然后,
7
存储在
属性中

当另一个模块导入
foo
时,它只是将对象从
sys.modules['foo']
中拉出,并获取修改后的值

当一个人

foo.bar = 7
from foo import bar
globals()['bar']
设置为reference
foo.bar
。当一个人后来这样做的时候

 bar = 7
globals()['bar']
不再引用
foo.bar
,而是引用
7
的副本。也就是说,只需替换导入模块全局范围内的原始绑定

在第一个示例中,一个是修改存储在
sys.modules
中的对象的属性,该属性对于导入该对象的所有模块都是通用的。在第二个示例中,一个是修改导入模块的全局范围

如果一个人要按照

 from foo import fobaz
 fobaz.foobar = 7
然后,该更改将传播到其他导入模块,因为其中一个模块不会覆盖全局引用,而是跟随它来修改它所指向的对象的属性。因此,本质上,只要不覆盖全局绑定,就应该能够修改可变对象


我认为类似这样的东西是最接近python中真正全局的东西。作为一种语言,它非常重视名称空间。

哇,我不知道这一点。回答得好。