为什么通过导入模块访问全局变量,而不是从模块导入变量?

Why does accessing globals work via import module, but not from module import var?

我一直在阅读和学习大量关于 python 的内容,但所有具有不同结果的导入变体有点令人困惑。

我遇到了一个问题,我导入的全局变量始终是默认值,即使我在该模块中调用了一个方法来操纵它。我是这样导入的:

from fona import connect, disconnect, CON

其中前两个是函数,最后一个是 var。前两个打开或关闭连接,我可以通过 var CON 访问它。当我这样做时,CON 将保持 None,即使 connect 正在成功初始化它(我有很多详细的输出来验证这一点)。越想越乱,想不通。写了一个post 与这个非常不同,然后我又有了一个想法。

import fona

然后我通过 fona 访问所有内容。connect/disco/CON。然后就可以了。我正在努力理解为什么并且找不到任何资源。是什么让这些进口产品与众不同?我很喜欢from x import y as z,但在这种情况下我似乎不能使用它。

from fona import CON

几乎与*相同:

import fona
CON = fona.CON

现在,如果 fona 在内部发生变化,从而 fona.CON 被替换为新值,这对您自己的变量没有影响。就像你说:

y = 1
x = y
y = 2

x 仍然是 1,尽管 y 现在是 2。


*除了后者留下名字 fona,前者没有。

在Python中,"global"表示"module-level"(实际上在运行时"global"变量是module对象实例的一个属性)。

现在这个声明:

from fona import CON

是语法糖:

import fona
CON = fona.CON 
del fona

所以此时我们有两个名称指向同一个对象 - fon.CON<yourothermodule>.CON

现在如果在 fona 中我们有一个重新绑定 fona.CON 的函数,即:

def foo():
    global CON
    con = "XXX"

调用此函数只会重新绑定 fona.CON,而不是 <yourothermodule> 中的 CON 变量。

如果您导入整个 fona 模块并使用 fona.CON,您确实会在调用 fona.foo() 后看到重订的效果,因为您实际上正在访问 fona 模块的属性,而不是您的本地(本地)属性。

实际上,在同一个模块中有两个字典,你会遇到完全相同的情况:

d1 = {"a":1}
d2 = {}
d2["a"] = d1["a"]
d1["a"] = 42 # this won't change d2["a"]
print d1, d2

事实上你甚至不需要字典,在同一个命名空间中的两个名字就足够了:

Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
>>> a = 1
>>> b = a
>>> print a
1
>>> print b
1
>>> b is a
True

如您所见,此时 b 不是 a 的 'copy',它实际上只是绑定到同一对象的另一个名称。现在如果我们重新绑定 a:

>>> a = 2
>>> print a
2
>>> print b
1
>>> b is a
False
>>> 

我们可以看到它不影响b,它只是让a指向另一个对象。