0

私は3つのファイルを持っています:

testimports モジュール:

#import moduleTwo
import moduleOne

hiString = "Hi!"

moduleOne.sayHi()

モジュールワン:

import moduleTwo

class sayHi():
    moduleTwo.printHi()

モジュール 2:

import testimports

def printHi():
    print(testimports.hiString)

を実行するtestimportsと、次のようになります。

Traceback (most recent call last):
  File "..file path snipped../testimports/src/testimports.py", line 2, in <module>
    import moduleOne
  File "..file path snipped../testimports/src/moduleOne.py", line 1, in <module>
    import moduleTwo
  File "..file path snipped../testimports/src/moduleTwo.py", line 1, in <module>
    import testimports
  File "..file path snipped../testimports/src/testimports.py", line 6, in <module>
    moduleOne.sayHi()
AttributeError: 'module' object has no attribute 'sayHi'

import moduleTwoただし、 の行のコメントを外すtestimportsと、プログラムは動作を停止する前にこの時点に到達します。

Traceback (most recent call last):
  File "..file path snipped../testimports/src/testimports.py", line 1, in <module>
    import moduleTwo
  File "..file path snipped../testimports/src/moduleTwo.py", line 1, in <module>
    import testimports
  File "..file path snipped../testimports/src/testimports.py", line 2, in <module>
    import moduleOne
  File "..file path snipped../testimports/src/moduleOne.py", line 3, in <module>
    class sayHi():
  File "..file path snipped../testimports/src/moduleOne.py", line 4, in sayHi
    moduleTwo.printHi()
AttributeError: 'module' object has no attribute 'printHi'

この循環依存の問題を解決するにはどうすればよいですか?

4

3 に答える 3

9

verisimilidude は正しい方向に沿っています。詳細を説明するために少し拡大します。

どちらの場合も、次のようになります。

  1. testimportsとして実行されます__main__
  2. testimports輸入品moduleOnemoduleOneファイルから読み取られ、インポートされたモジュールのリストに追加されるようになりましたsys.modules
  3. のインポートの実行は、インポートによってmoduleOne開始されmoduleTwoます。moduleTwoファイルから読み取られ、インポートされたモジュールのリストに追加されるようになりましたsys.modules。この段階では、 の残りの部分はmoduleOneまだ実行されていないためsayHi、定義されていないことに注意してください。
  4. moduleTwoをインポートして実行を開始しますtestimports。これは初めてtestimportsインポートされたものであり、 と同じであることとは関係ありません__main__。に挿入されるようになりましsys.modulesた。
  5. ここからが興味深いところです。新しくインポートされたtestimportsimports moduleOne. しかし、moduleOneはすでに にsys.modulesあるため、再度読み取られることはありません。次に、実行は の行に進みmoduleOne.sayHi()ます。しかし、 のインポートはmoduleOne完了してsayHiおらず、まだ定義されていません。したがって、エラーが発生します。

がコメント解除されている場合も、同様のループが発生しmoduleTwoます。本質的に、__main__インポートは、インポートが既にインポートされ、moduleTwoインポートtestimportsを通過します。これは順番にインポートしてから、まだ実行が完了していないため、まだ定義されていない呼び出しを試みます。moduleTwomoduleOnemoduleTwomoduleTwo.printHimoduleTwo

Anatoly Rr のソリューションはtestimports、インポート時にモジュールが他のモジュール機能を呼び出さないようにすることで、これらすべてを打破します。したがって、それがインポートされたときmoduleTwoは呼び出されませんmoduleOne.sayHi__main__すべてのインポートの後に実行が遅れるように、それはそれを実行するように開始されたときにのみ実行されます。

物語の教訓?可能であれば、Python での循環依存を避けてください

于 2010-09-18T00:25:01.453 に答える
2

書き換えtestimports.pyが役立つ場合があります:

import moduleOne

hiString = "Hi!"

def main ():
    moduleOne.sayHi()

if __name__ == "__main__":
    main ()
于 2010-09-17T23:15:33.193 に答える
2

あなたの問題は、Python が何かをインポートするときに、すべてのステートメントを基本レベルで実行することです。Module3 が元の testimports.py をモジュールとしてインポートすると、hiString が再度割り当てられ、呼び出しが再度行われます。呼び出しが定義内にあるため、Anatoly Rr のソリューションは機能します。def は__name__、モジュールがインポートされていることを Python ランタイムに示すため、呼び出されません。コマンドラインから呼び出されている場合、モジュール名は__main__.

于 2010-09-17T23:37:41.223 に答える