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

时间:2018-03-18 04:46:25

标签: python global-variables

是的:我知道我们不应该在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

为什么会这样?

2 个答案:

答案 0 :(得分:3)

让我们回顾一下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创建一个从x初始化为bug的本地foo()。在x模块中调用bug更改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
>>> from bug import *
>>> x, y
(0, [0])
>>> foo()
>>> x, y
(0, [100])
>>> 

更新:检查foo设置的utf8

>>> import sys
>>> sys.modules['bug'].x
100

答案 1 :(得分:1)

Python中的Globals对于模块是全局的,而不是跨所有模块。如果要使用模块错误中的x,请通过导入bug模块来使用它下方。

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

请勿使用from bug import *。这将创建一个新变量x,初始化为导入时引用的任何bug.x。如果你在bug.py文件中指定x = 50,那么在执行如下所示的语句from bug import *之后你将得到50。

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

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

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