4

我试图让第二个模块在循环导入中修改第一个模块的变量,但它似乎不起作用。

我有两个问题:1)为什么这不起作用/从语言开发的角度来看这是什么原因?2)是否有任何简单的解决方案可以让我以稍微不同的方式做同样的事情?

一个.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'
4

2 回答 2

9

发生的事情是,当b.py尝试 to时import a,没有条目 insys.modules因为条目在__main__. 这会导致导入机制重新导入模块并将其放在 name 下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。但总的来说,我真的不明白你为什么要这样做。可能有更好的方法来完成这项工作。

于 2010-11-27T04:59:37.757 回答
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'

一个.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'


注意:这种情况下不需要循环导入;并且循环导入会导致您的问题,因为它的行为不像您认为的那样。因此,只需一次导入,您就拥有了您想要的所有代码,并且您可以在两个模块中修改这些变量值。

于 2014-04-26T12:17:56.760 回答