web-dev-qa-db-ja.com

リロードする方法python `from module import *`を使用してインポートされたモジュール

私は この便利なQ&Areload(whatever_module)を使用できるか、またはPython 3、imp.reload(whatever_module)で使用できることを確認しました。

私の質問は、インポートするように_from whatever_module import *_と言った場合はどうなりますか?次に、reload()を使用するときに参照する_whatever_module_がありません。モジュール全体をグローバル名前空間に投げ込んだことに対して、あなたたちは私に怒鳴りつけますか? :)

45
murftown

"一般的にこれを行わない"コンセンサスに同意しますが、...

正解は次のとおりです。

import X
reload(X)
from X import Y  # or * for that matter
51
Catskul

import *は使用しないでください。読みやすさが損なわれます。

また、モジュールのリロードがほとんど役に立たないことにも注意してください。モジュールをリロードした後、プログラムがどのような状態になるかを予測することはできないため、理解できない、再現不可能なバグを取得するための優れた方法です。

8
Allen

from module import *

moduleからすべての「エクスポートされた」オブジェクトを取得し、それらをモジュールレベル(またはスコープレベルの名前)にバインドします。あなたはcanモジュールを次のようにリロードします:

reload(sys.modules['module'])

しかし、それは何の役にも立ちません。スコープレベルの名前は何でも、古いオブジェクトを指しています。

4
tzot

より明確な答えは、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
2
Eric O Lebigot

インポート時にモジュールをリロードする別の方法を見つけました:

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
1
ksiu

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
0
Ohad Cohen
import re

for mod in sys.modules.values():
    if re.search('name', str(mod)):
        reload(mod)
0
jennifer