217

速度とメモリの効率に関して、関数内に Python モジュールおよび/または関数をインポートすることの長所と短所は何ですか?

関数が実行されるたびに再インポートしますか、それとも関数が実行されるかどうかに関係なく最初に一度だけですか?

4

6 に答える 6

198

関数が実行されるたびに再インポートしますか?

いいえ; むしろ、Python モジュールは基本的にインポートされるたびにキャッシュされるため、2 回目 (または 3 回目、または 4 回目...) のインポートでは、実際にはインポート プロセス全体を再度実行する必要はありません。1

関数が実行されるかどうかにかかわらず、最初に 1 回インポートしますか?

いいえ、関数が実行された場合にのみインポートされます。2 , 3

利点については、場合によると思います。関数をめったに実行せず、モジュールを他の場所にインポートする必要がない場合は、その関数にのみインポートすることが有益な場合があります。または、名前の衝突や、モジュールまたはモジュールのシンボルをどこでも使用したくないその他の理由がある場合は、特定の関数にのみインポートすることをお勧めします。(もちろん、from my_module import my_function as fそのような場合には常にあります。)

一般的には、おそらくそれほど有益ではありません。実際、ほとんどの Python スタイル ガイドでは、プログラマーがすべてのインポートをモジュール ファイルの先頭に配置することを推奨しています。

于 2010-06-22T16:29:47.183 に答える
55

初めてimport gooどこからでも(関数の内部または外部)goo.py(または他のインポート可能なフォーム)がロードsys.modules['goo']され、このように構築されたモジュールオブジェクトに設定されます。プログラムの同じ実行内での将来のインポート(関数の内部または外部)は、適切なスコープでそれを検索しsys.modules['goo']てベアネームにバインドするだけです。goodictルックアップと名前バインディングは非常に高速な操作です。

とにかく最初importのプログラムがプログラムの実行で完全に償却されると仮定すると、「適切なスコープ」をモジュールレベルにするということは、、などの各使用goo.thisgoo.that2つのdictルックアップ(1つgooは属性名用、もう1つは属性名用)であることを意味します。それを「関数レベル」にすると、関数の実行ごとに1つの追加のローカル変数設定が支払われます(辞書ルックアップ部分よりもさらに高速です!)が、(ローカル変数ルックアップと交換して、非常に高速に)1つのdictルックアップを節約しますgoo.this(など)アクセス、基本的にそのようなルックアップにかかる時間を半分にします。

なんらかの形で数ナノ秒について話しているので、最適化する価値はほとんどありません。関数内にあることの潜在的に実質的な利点の1つimportは、プログラムの特定の実行でその関数がまったく必要ない場合があることです。たとえば、その関数はエラー、異常、および一般的なまれな状況を処理します。その場合、機能を必要としない実行ではインポートも実行されず(ナノ秒だけでなく、マイクロ秒の節約にもなります)、機能を必要とする実行のみが(適度ですが測定可能な)価格を支払います。

それはまだかなり極端な状況でのみ価値のある最適化であり、この方法でマイクロ秒を絞り出そうとする前に私が検討する他の多くのものがあります。

于 2010-06-22T16:36:27.690 に答える
20

関数が初めて実行されるときに一度インポートされます。

長所:

  • それらが使用されている関数に関連するインポート
  • パッケージ内の移動が容易な機能

短所:

  • このモジュールが依存している可能性のあるモジュールを確認できませんでした
于 2010-06-22T16:26:58.500 に答える
8

一般的に、「X は私のパフォーマンスを向上させますか?」と尋ねる代わりに、それを提案できますか? プロファイリングを使用して、プログラムが実際に時間を費やしている場所を特定し、最も利益が得られる場所に応じて最適化を適用しますか?

そして、プロファイリングを使用して、最適化が実際にあなたにも利益をもたらしていることを確認できます.

于 2010-06-22T18:48:25.300 に答える
7

関数内にインポートすると、関数が最初に実行されたときにモジュールが効果的にインポートされます。

上部でインポートする場合でも、関数の実行時にインポートする場合でも、同じように高速にインポートする必要があります。これは通常、def にインポートする正当な理由ではありません。長所?関数が呼び出されない場合、インポートされません。これは、ユーザーが特定の関数を使用する場合に、モジュールが特定のモジュールをインストールすることのみをユーザーに要求する場合、実際には合理的な理由です...

それがあなたがこれをしている理由ではない場合、それはほぼ間違いなく厄介な考えです.

于 2010-06-22T16:28:11.977 に答える
3

関数が初めて呼び出されたときに 1 回インポートされます。

めったに使用されず、インポートを必要とする唯一の関数がインポートされたモジュールにある場合、このようにすることを想像できます。かなり大げさなように見えますが...

于 2010-06-22T16:27:47.683 に答える