Pythonでは、import X
_を使用してインタープリターセッションでモジュールXをインポートし、外部でモジュールが変更されたら、reload(X)
を使用してモジュールをリロードできます。その後、変更はインタプリタセッションで利用可能になります。
_from X import Y
_を使用してモジュールXからコンポーネントYをインポートするときにこれも可能かどうか疑問に思っています。
Yはモジュール自体ではなく、モジュール内のコンポーネント(この場合はクラス)のみであるため、ステートメント_reload Y
_は機能しません。
インタプリタセッションを終了することなく(またはモジュール全体をインポートせずに)モジュールの個々のコンポーネントをリロードすることはまったく可能ですか?
編集:
明確にするために、問題はクラスまたは関数YをモジュールXからインポートし、パッケージXからモジュールYではなく、変更時にリロードすることです。
Yがモジュール(およびXがパッケージ)の場合、reload(Y)
は問題ありません。それ以外の場合は、良いPythonスタイルガイド(私の雇用主など)が言う理由がわかります。 to never何でもインポートexceptモジュール(これは多くの大きな理由の1つです-それでも、私はそれがいくら説明しても、関数とクラスを直接インポートし続けるnot良いアイデア;-)。
私のテストから。単純なreload(X)
を示唆するマークされた回答は機能しません。
私が正しい答えを伝えることができるものから:
# python3.x would require
# from importlib import reload
import X
reload( X )
from X import Y
私のテストは次のとおりでした(Python 2.6.5 + bpython 0.9.5.2)
X.py:
def Y():
print "Test 1"
bpython:
>>> from X import Y
>>> print Y()
Test 1
>>> # Edit X.py to say "Test 2"
>>> print Y()
Test 1
>>> reload( X ) # doesn't work because X not imported yet
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'X' is not defined
>>> import X
>>> print Y()
Test 1
>>> print X.Y()
Test 1
>>> reload( X ) # No effect on previous "from" statements
>>> print Y()
Test 1
>>> print X.Y() # first one that indicates refresh
Test 2
>>> from X import Y
>>> print Y()
Test 2
>>> # Finally get what we were after
まず、リロードを回避できる場合は、リロードを使用しないでください。しかし、理由があると仮定しましょう(つまり、IDLE内でのデバッグ)。
ライブラリをリロードしても、モジュールの名前空間に名前が戻されません。これを行うには、変数を再割り当てします。
f = open('Zoo.py', 'w')
f.write("snakes = ['viper','anaconda']\n")
f.close()
from Zoo import snakes
print snakes
f = open('Zoo.py', 'w')
f.write("snakes = ['black-adder','boa constrictor']\n")
f.close()
import Zoo
reload(Zoo)
snakes = Zoo.snakes # the variable 'snakes' is now reloaded
print snakes
他のいくつかの方法でこれを行うことができます。ローカルの名前空間を検索し、問題のモジュールからのものを再割り当てすることでプロセスを自動化できますが、私たちは十分に邪悪だと思います。
from modulename import func
import sys
reload(sys.modules['modulename'])
from modulename import func
これを行いたい場合:
from mymodule import myobject
代わりにこれを行います:
import mymodule
myobject=mymodule.myobject
これで、計画と同じ方法でmyobjectを使用できます(どこでも面倒で読みにくいmymodule参照なし)。
インタラクティブに作業していて、mymoduleからmyobjectをリロードする場合は、次を使用できます。
reload(mymodule)
myobject=mymodule.myobject
from X import Y
、次の2つのオプションがあります。
reload(sys.modules['X'])
reload(sys.modules[__name__]) # or explicitly name your module
または
Y=reload(sys.modules['X']).Y
いくつかの考慮事項:
A.インポートスコープがモジュール全体ではない場合(例:関数のインポート)-2番目のバージョンを使用する必要があります。
B. Yが別のモジュール(Z)からXにインポートされる場合-Zをリロードする前に、Xをリロードし、モジュールをリロードするよりも、すべてのモジュールをリロードする(例:[ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]
を使用) Yの値を更新しません。
reload()
モジュールX
、Y
からX
をインポートするreload()
モジュール。再読み込みしても、他の名前空間にバインドされている既に作成されたオブジェクトは変更されないことに注意してください(Alexのスタイルガイドに従っても)。
Jupyter環境で作業していて、すでにfrom module import function
は、マジック関数autoreload
を使用できます。
%load_ext autoreload
%autoreload
from module import function
IPythonでのautoreload
の紹介は here で与えられています。