在文件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
我不理解什么?
答案 0 :(得分:3)
foo
的全局命名空间仅导入当前命名空间一次(当您执行from foo import *
时)。之后,如果更改foo
的命名空间,它将不会反映在您当前的命名空间中。
请注意,您仍然可以更改foo
命名空间中的对象,并查看当前命名空间中的更改。这就是您在d
中看到更改的原因。您仍然可以引用位于d
命名空间中的同一对象foo
。
但是,当你设置:
x = 1
此重新绑定 foo
命名空间中的新对象。
答案 1 :(得分:2)
您的foo
模块和导入它的主模块(名为__main__
)具有单独的命名空间。
以下是发生的事情:
foo
设置foo
的全局变量x
以引用整数对象0
。__main__
复制到x
。foo.foo()
,设置foo
的全局变量x
以引用整数对象1
。__main__
的全局变量x
。因为您从未更改此x
引用的内容,所以它仍然引用0
,即打印的内容。简而言之,将名称导入模块不会在两个模块中的名称之间创建任何类型的绑定。它们最初引用相同的值,但如果一个名称重新绑定到另一个对象,则另一个名称不一定跟随。
这是(一)import foo
通常更好主意的原因。明确地在foo.x
中引用__main__
完全引用foo
的全局变量x
,并且即使它已被更改,也会引用该名称的当前值。