变量作用域如何与 python 导入一起使用

How does variable scoping work with python imports

我很难理解一个模块中的全局变量实际上是如何导入到另一个模块中的。假设我们有一个模块 mod1.py 编码如下:

#mod1.py
var1 = None
def test():
    global var1
    var1=1

并且,另一个模块mod2.py打算使用mod1.py,如下:


#mod2.py
from mod1 import *  #This may not be a good coding practice, but it's relevant to my question
print "var1="+str(var1)
test()
print "var1="+str(var1)

执行mod2时,打印语句打印:

var1=None
var1=None

这意味着作为"from mod1 import *"的结果导入的var1的值并没有通过调用test()对mod2进行任何更改。另一方面,如果我将 mod2 编码如下:


#mod2.py
import mod1
print "var1="+str(mod1.var1)
mod1.test()
print "var1="+str(mod1.var1)

第一条和第二条打印语句打印:

var1=None
var1=1

这意味着通过调用 mod1.test() 更改了 var1 的值。

为什么会这样?

一个常见的类比是将绳子系在气球上。将每条赋值语句想象成将字符串绑在气球上。例如

a = 1  # tie a string "a" to the `1` balloon
b = a  # tie a string to the same balloon that "a" is tied to.

将新事物分配给现有变量类似于剪切当前字符串并将其绑定到其他内容:

a = 2  # cut string tying "a" to 1 and tie it to the `2` balloon

在第一个版本 (from mod1 import *) 中,您基本上执行了一大堆赋值语句:

var1 = mod1.var1
...

现在,您有 2 根绳子系在 1 个气球上 -- mod1.var1mod2.var1。调用 test 函数后,您将 mod1.var1 的字符串剪断并将其系在“2”气球上。

在第二个示例 (import mod1) 中,您有一个字符串 (mod2.mod1) 绑定到 mod1 模块 ,但没有显式字符串绑定到 mod1.var1。所以现在当你重新绑定 mod1.var1 字符串时,你仍然可以用同样的方式查找它 -- 绑定到 mod1 的字符串没有改变,只有从 mod1mod1.var1.