2
で輸入からの参照

ショートを変更しますか?もう古いモジュールは必要ありませんが、別の名前で新しいモジュールをインポートすることはできません。 importlib.reload()は、所望の効果を持っていないと明らかにあなたが本当にsys.modulesは動的にPythonの

コンテキストと混乱すべきでない:
私は、スクリプト(A)を書き込むことによって、テストのワークフローを自動化しています。 テストスクリプトが提供されており、変更することはできません。
テストの対象は、サブフォルダに異なるバージョンがあるスクリプト(B)のクラスです。残念ながら、スクリプトBとクラスは常に同じ名前ですが、私はそのことについて何もできません。

main_folder 
├──script_a.py 
├──test_script.py 
│ 
├──version_1 
│ ├──script_b.py  
│ 
├──version_2 
│ ├──script_b.py 
│ 
├──version_3 
│ ├──script_b.py 

テストスクリプトはオブジェクトをインポートし、テストを実行します。

# test_script 
from script_b import my_class 

# creat instance of my_class 
# and test it 

script_aは、バージョンフォルダを反復し、script_bでテストスクリプトを実行します。 各反復において、テストスクリプトが対応するscript_bを見つけるように、1つのサブフォルダがインポートパスに追加されます。反復後にパスが削除されます。すでにtest_scriptのバージョンが含まれている場合sys.modules

# script_a 
import sys 
import os 
import importlib 

folders = ['version_1', 'version_2', 'version_3'] 
folders = [os.getcwd() + '/' + folder for folder in folders] 

for folder in folders: 
    sys.path.append(folder) 


    if 'test_script' in sys.modules: 
     importlib.reload(sys.modules['test_script']) 
    else: 
     importlib.import_module('test_script') 

    sys.path.remove(folder) 

問題:それはreload
はtest_scriptによってインポートされscript_b、には影響しません。したがって、私は異なるサブフォルダへのインポートパスを変更しますが、test_scriptは常にバージョン1で実行されます。 test_script自体を変更せずに、test_scriptの異なるバージョンのscript_bを使用するにはどうすればよいですか?

をフォローアップ: を元の質問が回答されているが、私は思っていた、どのように設計の観点から、この解決策はありますか?このテストプロセスを自動化するための、より洗練された方法がありますか?
私が見つけたことから、モジュールをリロードするのは良い方法ではありません。

答えて

1

質問を書いています。あなたがいつか誰かを助けることを願っています

test_script(またはscript_b)を変更できない場合でも、回避策があります。
関連するモジュールが既にインポートされている場合、import文は何もしないので、script_aに直接必要なパスからscript_bを再ロードできます。 sys.modulesで新しいバージョンに置き換えられたため、test_scriptのimport文は問題ありません。

更新コード:

# script_a 
import sys 
import os 
import importlib 

folders = ['version_1', 'version_2', 'version_3'] 
folders = [os.getcwd() + '/' + folder for folder in folders] 

for folder in folders: 
    sys.path.append(folder) 

    if 'test_script' in sys.modules: 
     importlib.reload(sys.modules['script_b'])  # this line added 
     importlib.reload(sys.modules['test_script']) 
    else: 
     importlib.import_module('test_script') 

    sys.path.remove(folder)