Python 为什么通过导入模块而不是从模块导入变量访问全局变量?
我已经阅读并学习了大量关于python的知识,但是所有具有不同结果的导入变体都有点令人困惑 我遇到了一个问题,我导入的全局变量始终是默认值,即使我在该模块中调用了一个方法来操作它。我是这样导入的:Python 为什么通过导入模块而不是从模块导入变量访问全局变量?,python,import,module,globals,Python,Import,Module,Globals,我已经阅读并学习了大量关于python的知识,但是所有具有不同结果的导入变体都有点令人困惑 我遇到了一个问题,我导入的全局变量始终是默认值,即使我在该模块中调用了一个方法来操作它。我是这样导入的: from fona import connect, disconnect, CON 其中前两个是函数,最后一个是变量。前两个是打开或关闭连接,我可以通过var CON访问该连接。当我这样做时,CON将保持为None,即使connect正在成功初始化它(我有很多详细的输出来验证)。我越来越胡闹,弄不明
from fona import connect, disconnect, CON
其中前两个是函数,最后一个是变量。前两个是打开或关闭连接,我可以通过var CON访问该连接。当我这样做时,CON将保持为None,即使connect正在成功初始化它(我有很多详细的输出来验证)。我越来越胡闹,弄不明白。在我还有一个想法之前,我写了一篇与这篇非常不同的文章
import fona
然后我通过fona.connect/disco/CON访问所有内容。然后它就起作用了。我正在努力寻找原因,但找不到任何资源。是什么让这些进口产品与众不同?我非常喜欢从x导入y作为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”表示“模块级”(实际上在运行时,“global”变量是模块
对象实例的属性)
现在我宣布:
from fona import CON
语法糖用于:
import fona
CON = fona.CON
del fona
所以在这一点上,我们有两个名字指向同一个对象-fon.CON
和.CON
现在,如果在fona
中,我们有一个重新绑定fona.CON
的函数,即:
def foo():
global CON
con = "XXX"
调用此函数只会重新绑定fona.CON
,而不是
中的CON
变量
相反,如果在中导入整个fona
模块并使用fona.CON
调用fona.foo()
后确实可以看到重新标记的效果,因为您实际访问的是fona
模块的属性,而不是本地(local to)属性
实际上,在同一个模块中有两个DICT时,您会遇到非常相同的情况:
d1 = {"a":1}
d2 = {}
d2["a"] = d1["a"]
d1["a"] = 42 # this won't change d2["a"]
print d1, d2
事实上,您甚至不需要dict,只要在同一名称空间中有两个名称就足够了:
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
的“副本”,它实际上只是绑定到同一对象的另一个名称。现在如果我们重新绑定a
:
>>> a = 2
>>> print a
2
>>> print b
1
>>> b is a
False
>>>
我们可以看到,它不会影响b
,它只会使a
指向另一个对象。谢谢。我错误地假设它将是对该变量的引用,而不是另一个实例/副本。它是一个引用-除非明确要求,否则Python不会复制任何内容。但是,当您重新绑定fona.CON
时,它不会更改先前绑定到fona.CON
的其他绑定-参见我答案中的dict示例。如果你使用一个可变对象,并对其进行变异,而不是将名称重新绑定到另一个对象上,你会发现两个名称都指向同一个对象(当然,直到其中一个名称反弹)。好了,现在它变得更有意义了。我错误地认为“从fona导入CON”会给我CON的引用,因此当fona模块(通过connect/disco)中更改CON时,CON在我的模块中是最新的。然而,创建了一个“本地”引用CON在导入时的状态,并且当CON(fona)被重新分配时,它不会。但是,调用fona.CON会检查fona模块。谢谢