115

Python では、 を使用してインタープリター セッションでモジュール X をインポートするimport Xと、モジュールが外部で変更され、モジュールを でリロードできますreload(X)。その後、通訳セッションで変更が利用可能になります。

を使用してモジュール X からコンポーネント Y をインポートするときに、これも可能かどうか疑問に思っていますfrom X import Y

reload YY はモジュール自体ではなく、モジュール内のコンポーネント (この場合はクラス) にすぎないため、ステートメントは機能しません。

インタープリター セッションを終了する (またはモジュール全体をインポートする) ことなく、モジュールの個々のコンポーネントを再読み込みすることはまったく可能ですか?

編集:

明確にするために、質問は、パッケージ X からのモジュール Y ではなく、モジュール Xからクラスまたは関数 Yをインポートし、変更をリロードすることです。

4

9 に答える 9

122

答え

私のテストから、単純なことを示唆するマークされた答えはreload(X)機能しません。

私が正しい答えを言うことができることから:

from importlib import reload # python 2.7 does not require this
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
于 2012-07-30T15:04:18.340 に答える
54

Y がモジュール (および X がパッケージ)reload(Y)である場合は問題ありません。そうでない場合は、優れた Python スタイル ガイド (私の雇用主のものなど) が、モジュール以外は何もインポートしないと言っている理由がわかります (これは、多くの大きな理由の 1 つです)。 -- それでも、関数やクラスを直接インポートし続ける人はいまだにいますが、それは良い考えではないと私がいくら説明しても;-)。

于 2009-11-16T03:44:48.037 に答える
17
from modulename import func

import importlib, sys
importlib.reload(sys.modules['modulename'])
from modulename import func
于 2014-02-27T16:00:57.233 に答える
6

まず、回避できるのであれば、リロードをまったく使用しないでください。ただし、理由があると仮定しましょう(つまり、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

これは他のいくつかの方法で行うことができます。ローカル名前空間を検索し、問題のモジュールからのものを再割り当てすることでプロセスを自動化できますが、私たちは十分に邪悪だと思います。

于 2009-11-16T06:21:51.513 に答える
4

これを行う場合:

from mymodule import myobject

代わりにこれを行います:

import mymodule
myobject=mymodule.myobject

これで、計画していたのと同じ方法で myobject を使用できるようになりました (面倒な判読不能な mymodule 参照がいたるところにありません)。

インタラクティブに作業していて、mymodule から myobject をリロードしたい場合は、次を使用できます。

reload(mymodule)
myobject=mymodule.myobject
于 2016-08-17T13:41:52.147 に答える
1
  1. reload()モジュールX
  2. reload()YからモジュールをインポートしていXます。

リロードしても、他の名前空間にバインドされている作成済みのオブジェクトは変更されないことに注意してください (Alex のスタイル ガイドに従っている場合でも)。

于 2009-11-16T05:58:28.213 に答える