我正在尝试允许第二个模块在循环导入中修改第一个模块的变量,但它似乎不起作用。
我有两个问题: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'
答案 0 :(得分:8)
当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
。总的来说,我真的不明白你为什么要这样做。可能有更好的方法来完成这项工作。
答案 1 :(得分:0)
执行此类任务的更好方法是在要更改它们的同一模块中声明变量。在b
中。然后在b
内导入a
,您可以随意执行。您可以使用不变的变量,就像您在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'
注:在这种情况下无需进行循环进口;和循环导入导致你的问题,因为它的行为不像你认为的那样。因此,只需一次导入,就可以获得您想要的所有代码,并且可以在两个模块中修改这些变量值。