导入时奇怪的全局变量行为



是的:我知道我们不应该在Python中使用全局变量,但我试图理解这种行为。

我有一个名为 bug.py 的文件:

x = 0

def foo():
global x
x = 100

if __name__ == '__main__':
foo()
print(x)

当我将其作为文件执行时,我得到了 100 的预期结果,见下文。

(mani) franz@ubuntu:~/dropboxpython/poolparty$ python bug.py
100

但是,当我在 repl 中做同样的事情时,x 不会变成 100,见下文

(mani) franz@ubuntu:~/dropboxpython/poolparty$ python
Python 3.6.4 | packaged by conda-forge | (default, Dec 23 2017, 16:31:06) 
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from bug import *
>>> x
0
>>> foo()
>>> x
0

为什么会这样?

让我们回顾一下from module import something语句的作用:

对该值的引用存储在本地命名空间中,使用 如果存在 as 子句中的名称,否则使用 名字

我还想补充一点,module已导入(即添加到sys.modules),但未创建名称module

第二个要点是整数是不可变的。不可变对象的行为如下所示,因为每个值都是一个单独的对象:

a = 0 # a-->0
b = a # a-->0<--b
a = 3 # 3<--a 0<--b; new object int(3) is created; b is still 0

因此,令人高兴的是,导入会创建一个本地x初始化为从零bugx。调用foo()更改xbug模块,但如上所示,它不会影响本地x


试试这个看看不可变x和可变y之间的区别:

x = 0
y = [0]
def foo():
global x, y
x = 100
y[0] = 100
if __name__ == '__main__':
foo()
print(x)
print(y)
从错误导入>>> *>>> x, y (0, [0])>>> foo()>>> x, y (0, [100])>>>

更新:检查foo设置的x

>>>导入系统>>> sys.modules['bug'].x 100

Python 中的全局变量是模块的全局变量,而不是所有模块的全局变量。如果要使用模块错误中的x,请通过导入bug模块来使用它,如下所示。

>>> import bug
>>> bug.x
0
>>> bug.foo()
>>> bug.x
100
>>> 

不要使用from bug import *。这将创建一个新变量x初始化为导入时引用的任何bug.x。如果您在文件中分配 x=50 bug.py 则在执行如下语句from bug import *后将获得 50。

>>> from bug import *
>>> x
50
>>> 

这个新变量x不会受到方法foo()赋值的影响。这就是第二次它不会给你变量 x 的值 100 的原因。

我试图简化它。希望这对:)有所帮助

相关内容

  • 没有找到相关文章

最新更新