インタラクティブなモジュールをPythonに再インポートする


383

できることは知っていますが、その方法を覚えていません。

どのようにしてPythonでモジュールを再インポートできますか?シナリオは次のとおりです。モジュールをインタラクティブにインポートして、いじくり回しますが、エラーが発生します。.pyファイルのエラーを修正した後、Pythonを終了せずに修正されたモジュールを再インポートします。どうすればできますか?



回答:


369

これはうまくいくはずです:

reload(my.module)

Pythonのドキュメントから

以前にインポートしたモジュールを再ロードします。引数はモジュールオブジェクトである必要があるため、以前に正常にインポートされている必要があります。これは、外部エディターを使用してモジュールソースファイルを編集し、Pythonインタープリターを離れずに新しいバージョンを試してみたい場合に便利です。

Python 3.4以降を実行している場合は、実行してから実行import importlibしますimportlib.reload(nameOfModule)

この方法を使用する際の注意事項を忘れないでください。

  • モジュールが再ロードされると、そのモジュール(モジュールのグローバル変数を含む)が保持されます。名前の再定義は古い定義を上書きするため、これは通常問題ではありませんが、モジュールの新しいバージョンが古いバージョンで定義された名前を定義していない場合、古い定義は削除されません。

  • モジュールがを使用して別のモジュールからオブジェクトをインポートする場合、他のモジュールをfrom ... import ...呼び出しreload()ても、そこからインポートされたオブジェクトは再定義されません。これを回避する1つの方法は、fromステートメントを再実行することです。別の方法は、代わりにimport修飾名(module.*name*)を使用することです。

  • モジュールがクラスのインスタンスをインスタンス化する場合、クラスを定義するモジュールを再ロードしても、インスタンスのメソッド定義には影響しません—古いクラス定義を引き続き使用します。派生クラスについても同様です。


26
を使用してモジュールをロードした場合from filename import *。リロードする方法は?
Peter Zhu

「from mod import fcn」の場合の@PeterZhuの場合、モジュールオブジェクトは名前空間に追加されません。そのため、モジュールを明示的にインポートして、後で再ロードできるようにする必要があります。import foo; from foo import bar; reload(foo)
テッド

再読み込みと自動再読み込みの魔法を試しましたが、コードの変更がエラーメッセージのスタックに反映されていますが、エラー自体は古いコードから外れているように見えます(たとえば、エラーの行はまったく同じです)以前と同じように、コメントに変更しましたが、コメントがエラーを引き起こすことはありません)。私のモジュールはJupyter拡張機能としてロードされていますが、これに別の回避策が必要かどうか誰かが知っていますか?ありがとう!
yifanwu

1
「名前としてmodをインポート」に従って関数をインポートした場合は、次のようにする必要があります。 'import importlib importlib.reload(name)'
Noe

このメソッドは、再ロードされたモジュールに対する他のモジュールの参照をオーバーライドしない場合があります。その解決策については、stackoverflow.com / a / 61617169/2642356を参照してください。
EZLearner

287

Python 3では、reloadは組み込み関数ではなくなりました。

Python 3.4以降を使用reloadしている場合は、importlib代わりにライブラリから使用する必要があります。

import importlib
importlib.reload(some_module)

Python 3.2または3.3を使用している場合:

import imp  
imp.reload(module)  

代わりに。http://docs.python.org/3.0/library/imp.html#imp.reloadを参照してください

を使用している場合はipython、必ずautoreload拡張機能の使用を検討してください。

%load_ext autoreload
%autoreload 2

多くのPythonコードはPython 2で記述されていますが、Python 3は日々実行可能なオプションになっています。先端をありがとう!
アーロンジョンソン

40
imp.reloadPython 3.4以降では非推奨です。代わりにimportlib.reload関数を使用してください。
jfs 2013年

1
@Andrewありがとう!私は%autoreloadを使用しました。すばらしいです。既に作成したオブジェクトは、クラスメソッドの再実装を必要とせずに、自動的に修正されたクラスメソッドの実装を取得しました
jeanmi

4
私は少し遅れだけど、私は何をリロードする必要があることは、モジュール内から関数やクラスであれば、これは仕事をしないと思う:私のインポートなステートメントをした場合from mymodule import myfunc、その後importlib.reload(myfunc)importlib.reload(mymodule.myfunc)importlib.reload(mymodule)すべてのNameErrorを与えます。
パフ

@Puff 関数を再インポートする方法については、以下の私の回答を参照しください
jss367

46

実際、Python 3では、モジュールimpは非推奨とマークされています。まあ、少なくとも3.4についてはそうです。

代わりに、モジュールのreload関数をimportlib使用する必要があります:

https://docs.python.org/3/library/importlib.html#importlib.reload

ただし、このライブラリには、最後の2つのマイナーバージョンでいくつかのAPIの変更があったことに注意してください。


6

モジュールから特定の関数またはクラスをインポートする場合は、これを行うことができます。

import importlib
import sys
importlib.reload(sys.modules['my_module'])
from my_module import my_function

0

提供された回答は特定のモジュールで機能しますが、この回答に記載されているように、サブモジュールは再読み込みされません。

モジュールがを使用して別のモジュールからオブジェクトをインポートする場合、他のモジュールをfrom ... import ...呼び出しreload()ても、そこからインポートされたオブジェクトは再定義されません。これを回避する1つの方法は、fromステートメントを再実行することです。別の方法では、代わりにimport修飾名(module.*name*)を使用します。

ただし、__all__変数を使用してパブリックAPIを定義する場合、すべてのパブリックに利用可能なモジュールを自動的に再ロードすることが可能です。

# Python >= 3.5
import importlib
import types


def walk_reload(module: types.ModuleType) -> None:
    if hasattr(module, "__all__"):
        for submodule_name in module.__all__:
            walk_reload(getattr(module, submodule_name))
    importlib.reload(module)


walk_reload(my_module)

ただし、前の回答に記載されている警告は引き続き有効です。特に、__all__変数で説明されているパブリックAPIの一部ではないサブモジュールを変更しても、この関数を使用したリロードの影響は受けません。同様に、サブモジュールの要素を削除しても、リロードでは反映されません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.