4

循環インポートで 2 番目のモジュールが最初のモジュールの変数を変更できるようにしようとしていますが、うまくいかないようです。

2 つの質問があります: 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'
4

2 に答える 2

9

何が起こっているかというと、 をb.pyしようとすると、エントリが の下import aにあるため、 にエントリがありません。これにより、インポート メカニズムがモジュールを再インポートし、名前の下に配置します。そのため、モジュールとまったく関係のないモジュールがあります。このようなものに変更すると、うまくいきます。sys.modules__main__aa__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__']が 2 つの異なるオブジェクトを参照していることを明確に示しています。解決策は、おそらく次の行を最初の行として配置することです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'

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'


注: この場合、循環インポートは必要ありません。循環インポートは、思ったように動作しないため、問題を引き起こしています。したがって、1 回のインポートだけで、コードに必要なものがすべて揃っており、これらの変数の値を両方のモジュール内から変更できます。

于 2014-04-26T12:17:56.760 に答える