1

私のアプリケーションでは、次のものがあります。

...
folder_a/
    __init__.py
    a.py
    folder_b/
        __init__.py
        b1.py 
        b2.py
        ...

そして、変数に基づいて、モジュールを からfolder_bに動的にロードする必要があります。でこれを行うには、次のようにします。a.pymodule_from_ba.py

mymodule = __import__("folder_b.%s" % module_from_b, globals(), locals(), fromlist=["*"])

これはループ内に存在するため、つまり何度も呼び出されるため、パフォーマンスやその他に影響があるのでしょうか? もしそうなら、動的モジュールローディングの機能を維持しながらそれを軽減する方法はありますか?

4

3 に答える 3

1

私はそれをベンチマークしたことはありませんが、実行中のインタープリターに以前にインポートされたモジュールを (動的であれ静的であれ) (完全に無関係なコードであっても) インポートするのはかなり安いはずです。実際に行う必要があるのは、(成功した) 辞書検索だけです。

もちろん、新しいモジュールをインポートすると、モジュール内のすべてのコードが実行され、ファイル システム検索が実行されます。

したがって、比較的少数のモジュール セットから動的に選択されたモジュールを繰り返しインポートする場合、各特定のモジュールが最初に使用されるときの遅延を許容できる限り (どのくらいの遅延はモジュールによって異なります); しばらくすると、インポートしようとしているほとんどすべてのモジュールが既にインポートされているため、__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):
    ...

モジュールは他のものと同じようにオブジェクトなので、リストやオブジェクト、または名前で行っていることは何でも保存できます。通常、モジュールを直接渡す方が、名前をモジュールのプロキシとして渡し、後でインポートするよりもクリーンです。

于 2012-05-23T21:48:25.017 に答える
0

import ステートメントが__import__()バイトコードでの呼び出しとして表されることに違いはありません。次の 2 つは同等です。

import spam
spam = __import__('spam', globals(), locals(), [], -1)
于 2012-05-24T00:04:43.493 に答える
-1

何度も実行する可能性がある場合は、そのモジュールが現在の名前空間にすでに存在するかどうかを確認し、それだけではない場合はインポートしてください。

if 'module_I_need_to_load' not in dir():
    from b import module_I_need_to_load
# Or you can look in vars() instead if you have a
# hell of a lot of modules loaded up as dir is a 
# list and vars is a dictionary which will have a
# faster lookup time when you start having a lot of
# elements
if 'module_I_need_to_load' not in vars():
    from b import module_I_need_to_load
于 2012-05-23T20:07:30.180 に答える