17

誰かが次のコードを実行する理由を説明できますか:

ファイル " hello.py ":

import hello
print "hello"
hello = reload(hello)

次のように実行するとpython hello.py、次のように出力されますか?

hello
hello
hello
hello

なんで4回?モジュールが既にインポートされている場合、再度インポートされないことはわかっていますが、 reload は、既にロードされている場合でもモジュールを強制的にリロードします。結果として、「hello」プリントの制限が解除されると予想していました。

reloadモジュールをリロードしないようにするにはどうすればよいですか?

4

2 に答える 2

12

python hello.py(A) はコードを 1 回実行し、(A) がimport helloコードを呼び出すと (B) が再度実行され、(A) と (B) が を呼び出すreload(hello)と、コードはさらに 2 回実行され、合計で 4 回実行されます。

一般に、プログラムの存続期間中、モジュールのコードは次の時点で実行されます。

  • メインモジュールの場合は1回
  • 任意のモジュール (それ自体を含む) によって初めてインポートされたとき
  • モジュールでいつでもreload()呼び出されます

が再帰的に呼び出されない理由については、reload()これを防ぐために PyImport_ReloadModule() 関数 (CPython、ファイルは import.c) への早期終了ポイントがあります。

http://svn.python.org/view/python/trunk/Python/import.c?view=markup#l2646

    ...
    existing_m = PyDict_GetItemString(modules_reloading, name);
    if (existing_m != NULL) {
        /* Due to a recursive reload, this module is already
           being reloaded. */
        Py_INCREF(existing_m);
        return existing_m;
    }
    ... load module code is below here
于 2012-06-08T19:47:34.813 に答える
8

reloadモジュールの再帰的なリロードを避けるために、現在リロードしているモジュールのリスト (実際には dict) を保持します。

http://hg.python.org/cpython/file/e6b8202443b6/Lib/imp.py#l236を参照してください。

これ自体は文書化されていませんが、おそらく信頼できると思います。

于 2012-06-08T19:56:58.267 に答える