为什么我无法在Python中更改其他模块的变量?
我正在尝试让第二个模块能够修改第一个模块的变量,但这似乎不太奏效。
我有两个问题:1) 为什么这样不行,从语言开发的角度来看,这背后的原因是什么? 2) 有没有什么简单的方法可以让我以稍微不同的方式做到这一点?
a.py:
import b
test1 = 'a'
test2 = None
test3 = '3'
if __name__ == '__main__':
print test1, test2, test3 #prints 'a', None, 3
b.changeVars()
print test1, test2, test3 #prints 'a', None, 3 (i.e. nothing has changed)
b.py:
import a
def changeVars():
print a.test1, a.test2, a.test3 #prints 'a', None, 3
a.test1 = 'NEW VAR 1'
a.test2 = 'NEW VAR 2'
a.test3 = 'NEW VAR 3'
print a.test1, a.test2, a.test3 #prints 'NEW VAR 1', 'NEW VAR 2', 'NEW VAR 3'
2 个回答
0
做这种事情有个更好的方法,就是在你想要修改变量的模块里声明这些变量。在这个例子中,就是在 b
里。然后在 a
中导入 b
,这样你就可以随心所欲地使用这些变量了。你可以像在 a
中声明的一样使用这些变量,也可以对它们进行修改。看看这个:
b.py
test1 = 'a'
test2 = None
test3 = '3'
def changeVars():
global test1,test2,test3
test1 = 'NEW VAR 1'
test2 = 'NEW VAR 2'
test3 = 'NEW VAR 3'
print test1, test2, test3 #prints 'NEW VAR 1', 'NEW VAR 2', 'NEW VAR 3'
a.py
import b
if __name__ == '__main__':
print b.test1, b.test2, b.test3 #prints 'a', None, 3
b.changeVars()
print b.test1, b.test2, b.test3 #prints 'NEW VAR 1', 'NEW VAR 2', 'NEW VAR 3'
注意:在这种情况下不需要循环导入;循环导入会导致你的问题,因为它的表现和你想象的不一样。所以,只需一个导入,你就能在代码中实现你想要的功能,并且可以在两个模块中修改这些变量的值。
9
发生的事情是,当 b.py
尝试 import a
时,sys.modules
中没有对应的条目,因为这个条目是在 __main__
下。这导致导入机制重新导入这个模块,并将其放在 a
这个名字下。所以现在就有了一个 a
模块和一个完全不相关的 __main__
模块。把 b.py
改成下面这样就能解决这个问题。
import sys
a = sys.modules['__main__']
def changeVars():
print a.test1, a.test2, a.test3 #prints 'a', None, 3
a.test1 = 'NEW VAR 1'
a.test2 = 'NEW VAR 2'
a.test3 = 'NEW VAR 3'
print a.test1, a.test2, a.test3 #prints 'NEW VAR 1', 'NEW VAR 2', 'NEW VAR 3'
这样做的结果是
aaron@aaron-laptop:~/code/tmp$ python a.py
a None 3
a None 3
NEW VAR 1 NEW VAR 2 NEW VAR 3
NEW VAR 1 NEW VAR 2 NEW VAR 3
aaron@aaron-laptop:~/code/tmp$
为了更好地理解发生了什么,可以考虑这些文件:
#a.py
import b
import a
test = 'Foo'
if __name__ == '__main__':
print test #prints 'Foo'
b.changeVars()
print a.test, test # prints 'Foo', 'Bar'
和
#b.py
import a as a1
import sys
a2 = sys.modules['__main__']
def changeVars():
print a1.test, a2.test # Prints 'Foo', 'Foo'
a2.test = 'Bar'
print a1.test, a2.test # Prints 'Foo', 'Bar'
这将输出
Foo
Foo Foo
Foo Bar
Foo Bar
这清楚地显示了 sys.modules['a']
和 sys.modules['__main__']
指向两个不同的对象。解决办法可能是在 a.py
的第一行加上以下内容
import __main__ as a # due to Ignacio Vazquez-Abrams
这样做可以让其他模块也能 import a
。不过,总的来说,我真的不明白你为什么要这样做。可能还有更好的方法来完成这个任务。