私は この便利なQ&A でreload(whatever_module)
を使用できるか、またはPython 3、imp.reload(whatever_module)
で使用できることを確認しました。
私の質問は、インポートするように_from whatever_module import *
_と言った場合はどうなりますか?次に、reload()
を使用するときに参照する_whatever_module
_がありません。モジュール全体をグローバル名前空間に投げ込んだことに対して、あなたたちは私に怒鳴りつけますか? :)
"一般的にこれを行わない"コンセンサスに同意しますが、...
正解は次のとおりです。
import X
reload(X)
from X import Y # or * for that matter
import *
は使用しないでください。読みやすさが損なわれます。
また、モジュールのリロードがほとんど役に立たないことにも注意してください。モジュールをリロードした後、プログラムがどのような状態になるかを予測することはできないため、理解できない、再現不可能なバグを取得するための優れた方法です。
あ
from module import *
module
からすべての「エクスポートされた」オブジェクトを取得し、それらをモジュールレベル(またはスコープレベルの名前)にバインドします。あなたはcanモジュールを次のようにリロードします:
reload(sys.modules['module'])
しかし、それは何の役にも立ちません。スコープレベルの名前は何でも、古いオブジェクトを指しています。
より明確な答えは、Catskulの良い答えと、Ohad Cohenによるsys.module
の使用と直接的な再定義を組み合わせたものです。
import sys
Y = reload(sys.module["X"]).Y # reload() returns the new module
実際、import X
を実行すると、次のコードで再定義される可能性がある新しいシンボル(X
)が作成されますが、これは不要です(sys
は一般的なモジュールなので、これにより起こらない)。
ここで興味深い点は、from X import Y
は名前空間にX
を追加しないが、既知のモジュール(sys.modules
)のリストにモジュールX
を追加することです。これにより、リロードするモジュール(およびその新しいコンテンツにアクセス)。
より一般的には、インポートされた複数のシンボルを更新する必要がある場合は、次のようにインポートする方が便利です。
import sys
reload(sys.module["X"]) # No X symbol created!
from X import Y, Z, T
インポート時にモジュールをリロードする別の方法を見つけました:
from directory.module import my_func
モジュールが一般的にどのようにインポートされているかを知るのはうれしいことです。モジュールはsys.modules
辞書で検索されます。 sys.modulesにすでに存在する場合-モジュールは再度インポートされません。
したがって、モジュールをリロードしたい場合は、sys.modulesからモジュールを削除して再度インポートするだけです。
import sys
from directory.module import my_func
my_func('spam')
# output: 'spam'
# here I have edited my_func in module.py
my_func('spam') # same result as above
#output: 'spam'
del sys.modules[my_func.__module__]
from directory.module import my_func
my_func('spam') # new result
#output: 'spam spam spam spam spam'
スクリプト全体を実行するときにリロードされたモジュールを取得したい場合は、例外ハンドラーを使用できます。
try:
del sys.modules[my_func.__module__]
except NameError as e:
print("""Can't remove module that haven't been imported.
Error: {}""".format(e))
from utils.module import my_func
..........
# code of the script here
from whatever_module import whatever
を使用してインポートする場合、whatever
はインポートモジュールの一部としてカウントされるため、再ロードするには、モジュールを再ロードする必要があります。ただし、モジュールをリロードするだけで、古いwhatever
-すでにインポートされたwhatever_module
から取得できるため、リロードする必要があります(whatever_module)。その後、モジュールをリロードします。
# reload(whatever_module), if you imported it
reload(sys.modules['whatever_module'])
reload(sys.modules[__name__])
from whatever_module import whatever
を使用した場合も検討できます
whatever=reload(sys.modules['whatever_module']).whatever
または
whatever=reload(whatever_module).whatever
import re
for mod in sys.modules.values():
if re.search('name', str(mod)):
reload(mod)