0

同じディレクトリに 2 つのモジュールがあります。

私はPython 3.2を使用しています

1つはa.py次のようなものです:

import b
class orig:
    def test(self):
        print("hello")


o = orig()
o.test()

もう一つはb.py次のようなものです:

from a import orig
orig.test=lambda self: print("wrong")

次のようなコマンドを実行すると:

python a.py

出力には1 つしか表示されないはずhelloですが、出力には 2 つ表示helloされます。それぞれhello別の行に。

また、2 つのモジュールが相互にインポートされた状況を Python がどのように処理するかについても混乱しています。

誰かがこれについてアイデアを持っていますか?

4

3 に答える 3

2

で行っているように、Pythonスクリプトを直接実行するとpython a.py、Pythonインタープリターはそのファイルのモジュールパスがどうあるべきかを推測しません。というモジュールを作成して__main__実行するだけです。

もう 1 つの微妙な点は、Python がインポートに遭遇するたびに、最初にモジュールを作成して格納しsys.modules、同じモジュールの他のすべてのインポートが同じモジュール オブジェクトを生成するようにすることです。ブレッドクラムが残っている場合にのみ、そのモジュールを実装する Python コードの実行が開始されます。

python a.pyシェル コンソールで入力すると、Python が__main__モジュールを作成し、そのファイルの評価を開始します。

the file being parsed
  |
  |       the module being imported       
  |         |     
./a.py  __main__  1:  import b

わかりました。まず、a.py何かをインポートします。以前にインポートされたことがないため、パスを検索して見つけb.pyます。まだ別のファイルをインポートしようとしているので、それを示すために少しインデントします。

    ./b.py  b  1:  from a import orig

で最初に起こるb.pyことは、インポートを試みることaです。しかし、aインポートされたこともありません。Python がパスを検索すると、a.py

        ./a.py  a  1:  import b

おなじみのようです。しかし、bインポートされています。これbは同じものになります (まだインポート中です!

        ./a.py  a  2:  class orig:
        ./a.py  a  3:      def test(self):
        ./a.py  a  4:          print("hello")
        ./a.py  a  5:  
        ./a.py  a  6:  
        ./a.py  a  7:  o = orig()
        ./a.py  a  8:  o.a()

わかった。クラスが作成され、インスタンス化され、何らかの出力が発生します。 aインポートが完了しました。bfrom インポートを使用したため、それは良いことです。つまりorig、今までに存在する必要があることを意味します。そうしないと、インポートが失敗します。

    ./b.py  b  2:  orig.test=lambda self: print("wrong")

bモンキーパッチa.orig(注;ありません__main__.orig)。 bこれでインポートも完了です。

./a.py  __main__  2:  class orig:
./a.py  __main__  3:      def test(self):
./a.py  __main__  4:          print("hello")
./a.py  __main__  5:  
./a.py  __main__  6:  
./a.py  __main__  7:  o = orig()
./a.py  __main__  8:  o.a()

__main__クラスを定義し、それをインスタンス化し、いくつかの出力を出力しています。また、これは変更された b__main__.origではなく、class の定義であることに注意してください。a.orig

混乱が解消されることを願っています。

于 2013-01-06T16:08:44.160 に答える
0

a.py を 2 回実行しているため、2 行の出力が得られます。1 回はメイン プログラムとして、もう 1 回は b にインポートされたときです。循環インポートを避け、メイン プログラムを絶対にインポートしないでください。

メイン プログラムをインポートすることのもう 1 つの副作用:origこのプログラムでは、実際には 2 つのクラスの名前が付けられています。

于 2013-01-06T16:00:13.573 に答える
0

@TokenMacGuy と @Ned の 2 番目に: a.py の末尾を次のように置き換えた場合:

if __name__ == "__main__":
    o = orig()
    o.test()

「こんにちは」が 1 つだけ表示されます。

そして、確かに: 循環依存を避けてください!

于 2013-01-06T17:12:14.117 に答える