2010-11-27 102 views
4

我想让第二个模块修改第一个循环导入的变量,但它似乎不工作。为什么我不能在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' 

回答

7

发生了什么事是,当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' 

产生

[email protected]:~/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 
[email protected]:~/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

`import __main__ as`但是,不要这样做。 – 2010-11-27 05:38:48

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' 


注:没有必要在这种情况下,圆形的进口;而循环导入导致你的问题,因为它不像你认为它应该。因此,只需一次导入,就可以获得代码所需的全部内容,并且可以在两个模块中修改这些变量值。

相关问题