私はそれをベンチマークしたことはありませんが、実行中のインタープリターに以前にインポートされたモジュールを (動的であれ静的であれ) (完全に無関係なコードであっても) インポートするのはかなり安いはずです。実際に行う必要があるのは、(成功した) 辞書検索だけです。
もちろん、新しいモジュールをインポートすると、モジュール内のすべてのコードが実行され、ファイル システム検索が実行されます。
したがって、比較的少数のモジュール セットから動的に選択されたモジュールを繰り返しインポートする場合、各特定のモジュールが最初に使用されるときの遅延を許容できる限り (どのくらいの遅延はモジュールによって異なります); しばらくすると、インポートしようとしているほとんどすべてのモジュールが既にインポートされているため、__import__
呼び出しが安くなります。
検討できる代替設計: 必要なモジュールの合計セットが事前に (静的または動的に) わかっている場合は、ループの前にそれらを事前にインポートして、Python のインポートされたモジュール セットを「ウォームアップ」することができます。b に使用されないモジュールがあまりない場合は、 b's のすべてをインポートできます__init__.py
。
そうすれば、インポートの遅延が開始時に邪魔にならgetattr
なくなり、 b パッケージで を使用して、 を使用する代わりにモジュールを動的に取得できます__import__
。非常に多くのモジュールをロードしていて、インポート コストをループ全体に分散させたい場合、または多くのモジュールがあり、比較的少数のモジュールしか必要とせず、どのモジュールが先にあるのかを知るのが難しい場合は、あまり良いオプションではありません。時間。
インポートするモジュールを特定している場所で、定数文字列を選択している場合 (たとえば、構成ファイルやユーザー入力から読み取ったものではない場合) に機能する、さらに優れた別のアプローチがあります。モジュールの名前を先に渡して最終的に他の場所にインポートするのではなく、モジュールをその場でインポートして、モジュール自体を渡して最終的に他の場所で使用しないのはなぜですか? でっちあげの例として、あなたが何をしているのか私にはわからないので、以下の代わりに:
for module_name in ['b1', 'b2', 'b3', 'b4']:
function_using_module(module_name)
def function_using_module(module_name):
module = __import__(...)
...
あなたがすることができます:
from folder_b import b1, b2, b3, b4
for module in [b1, b2, b3, b4]:
function_using_module(module)
def function_using_module(module):
...
モジュールは他のものと同じようにオブジェクトなので、リストやオブジェクト、または名前で行っていることは何でも保存できます。通常、モジュールを直接渡す方が、名前をモジュールのプロキシとして渡し、後でインポートするよりもクリーンです。