为什么全局变量不能像导入时那样工作?

时间:2013-11-25 23:14:43

标签: python variables scope

在文件foo.py中我有:

d = {}
d['x'] = 0
x = 0

def foo():
    global d
    global x
    d['x'] = 1
    x = 1

然后在翻译中:

>>> from foo import *
>>> d['x']
0
>>> x
0
>>> foo()
>>> d['x']
1
>>> x
0

我期待这个:

>>> x
1

我不理解什么?

2 个答案:

答案 0 :(得分:3)

foo的全局命名空间仅导入当前命名空间一次(当您执行from foo import *时)。之后,如果更改foo的命名空间,它将不会反映在您当前的命名空间中。

请注意,您仍然可以更改foo命名空间中的对象,并查看当前命名空间中的更改。这就是您在d中看到更改的原因。您仍然可以引用位于d命名空间中的同一对象foo

但是,当你设置:

x = 1

重新绑定 foo命名空间中的新对象。

答案 1 :(得分:2)

您的foo模块和导入它的主模块(名为__main__)具有单独的命名空间。

以下是发生的事情:

  1. 导入foo设置foo的全局变量x以引用整数对象0
  2. 此引用将作为全局变量__main__复制到x
  3. 您调用foo.foo(),设置foo的全局变量x以引用整数对象1
  4. 您打印__main__的全局变量x。因为您从未更改此x引用的内容,所以它仍然引用0,即打印的内容。
  5. 简而言之,将名称导入模块不会在两个模块中的名称之间创建任何类型的绑定。它们最初引用相同的值,但如果一个名称重新绑定到另一个对象,则另一个名称不一定跟随。

    这是(一)import foo通常更好主意的原因。明确地在foo.x中引用__main__完全引用foo的全局变量x,并且即使它已被更改,也会引用该名称的当前值。