以下是更新全局变量问题的简化版本 -
在test.py
我有:
k1 = 1
def set_v(k, v):
if k in globals():
globals()[k] = v;
read_v()
def read_v():
print("after {}".format(k1))
在执行以下操作后,代码从python解释器运行:
from test.py import *
...产量
>>> k1
1
>>> set_v('k1',2)
after 2
>>> set_v('k1',3)
after 3
>>> k1
1
我无法理解这一点。
k1
具有全局范围read_v()
在全局dict
中看到它。
为什么解释器可见的全局k1
没有被更改?
我试过了setattr(module, var, val)
......但这与此无异。
答案 0 :(得分:4)
Python中的Globals只是模块中的全局。
如果要修改导入模块中的全局,则需要使用module.variable
访问它。
在测试环境中,这意味着:
import test.py as test
from test.py import *
print(test.k1)
set_v('k1',2)
set_v('k1',3)
print(test.k1)
输出:
1
after 2
after 3
3
答案 1 :(得分:3)
执行from test import *
时,将所有这些对象和函数放入命名空间。您引用了k1
,而test
也引用了k1
。但参考文献并不相同。他们是不同的。
试试这个:
>>> import test
>>> from test import *
>>> set_v('k1', 3)
after 3
>>> k1
1
>>> test.k1
3
修改您的set_v
功能以打印出ID。您会看到test
k1
和导入您的REPL会话的k1
不同。
结论:k1
的每个版本都位于各自的名称空间中。