16

率直に言って、Pythonコードを変更した後に再ロードするというビジネス全体が混乱しています。少し前import <module>に、インタープリターで呼び出す方が更新されたコードを取得するためfrom <module> import <class/function>に呼び出すことができるため、よりも優れていることがわかりました。reload(module)

しかし、私は今、より複雑な問題を抱えています。それで、このファイルmodule1.pyがあり、上部に次のように書かれています:

from module2 import <class1>, <function1>, etc.

次に、module2 内のコードを変更します。reload(module1)module2 のコードが module1 の先頭にインポートされているにもかかわらず、呼び出しによって module2 で変更されたコードがリロードされないことが判明しました。インタープリターを再起動せずにすべてをリロードする方法はありますか?

スタイルについて誰かが私の主張を始める前に、私はただそれを言います:

  1. reload私はインタープリターからのみ呼び出し、アクティブなコードでは呼び出しません。この質問は、新しいコードをテストしているときに関するものです。
  2. から呼び出すことはありません<module> import *。読みやすさを損なうことはわかっています。
4

6 に答える 6

10

モジュールをリロードするには、 を使用する必要があり、リロードするモジュールでそれをreload使用する必要があります。モジュールをリロードしても、そのモジュールによってインポートされたすべてのモジュールが再帰的にリロードされるわけではありません。その 1 つのモジュールをリロードするだけです。

モジュールがインポートされると、そのモジュールへの参照が保存され、後でそのモジュールをインポートすると、インポート済みで保存済みのバージョンが再利用されます。reload するとmodule1from module2 import ...ステートメントが再実行されますが、既にインポートされているバージョンのmodule2を再ロードせずに再利用するだけです。

import module2これを修正する唯一の方法は、代わりに (または追加で)コードを変更することfrom module2 import ...です。モジュール自体がインポートされ、名前にバインドされていない限り (つまり、import moduleステートメントだけでなくステートメントを使用してfrom module import stuff)、モジュールを再ロードすることはできません。

どちらの形式のインポートも使用できることに注意してください。インポートしたモジュールをリロードすると、その後のfromインポートに影響します。つまり、次のことができます。

>>> import module
>>> from module import x
>>> x
2
# Change module code here, changing x to 3
>>> reload(module)
>>> from module import x
>>> x
3

これは、モジュールをリロードしながら必要なものを参照するために短いプレフィックスのない名前を使用できるため、インタラクティブな作業に便利です。

于 2012-12-23T23:10:43.413 に答える
2

わかりました、コードを変更せずに答えとして適格かどうかはわかりませんが、... 少なくとも、module1.

module1 をロードする前後にロードされたモジュールを保存しreload、次のようなメソッドを提供するモジュール ラッパー クラスを使用できます。

import sys

class Reloader(object):
    def __init__(self, modulename):
        before = sys.modules.keys()
        __import__(modulename)
        after = sys.modules.keys()
        names = list(set(after) - set(before))
        self._toreload = [sys.modules[name] for name in names]

    def do_reload(self):
        for i in self._toreload:
            reload(i)

次に、module1 を次のようにロードします。

reloader = Reloader('module1')

module2 を変更して、インタープリターで次のようにリロードできることを確認してください。

reloader.do_reload()
于 2013-07-01T22:26:08.943 に答える
2

モジュールのリロードが上手になるのではなく、インタープリターの再起動が上手になる可能性があります。たとえば、セットアップ コードを独自のファイルに入れ、次のように実行できます。

$ python -i setup.py
>>>

これにより setup.py が実行され、インタラクティブなプロンプトが表示されます。または、インタラクティブなプロンプトで多くの作業を行うのではなく、作業を行う自動テストを記述します。

そうです、Python でモジュールをリロードするのは面倒です。言語のセマンティクスにより、プロセスの実行中にコードを変更することは困難です。モジュールをリロードする必要がないことを学びましょう。

于 2012-12-23T23:48:28.657 に答える
1

インポートは名前空間に名前を割り当てるだけであることを忘れないでください。したがって、リロード後にその名前を再割り当てできます。

>>> reload(module2)
>>> module1.class1 = module2.class1

class1これで、 module1 内のオブジェクトは、module2 から再ロードされたバージョンを参照します。

于 2012-12-23T23:28:47.240 に答える