Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么通过导入模块而不是从模块导入变量访问全局变量?_Python_Import_Module_Globals - Fatal编程技术网

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

Python 为什么通过导入模块而不是从模块导入变量访问全局变量?,python,import,module,globals,Python,Import,Module,Globals,我已经阅读并学习了大量关于python的知识,但是所有具有不同结果的导入变体都有点令人困惑 我遇到了一个问题,我导入的全局变量始终是默认值,即使我在该模块中调用了一个方法来操作它。我是这样导入的: from fona import connect, disconnect, CON 其中前两个是函数,最后一个是变量。前两个是打开或关闭连接,我可以通过var CON访问该连接。当我这样做时,CON将保持为None,即使connect正在成功初始化它(我有很多详细的输出来验证)。我越来越胡闹,弄不明

我已经阅读并学习了大量关于python的知识,但是所有具有不同结果的导入变体都有点令人困惑

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

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模块。谢谢