使用時のPythonモジュールのインポート


8

私自身の個人的なPythonライブラリでは、次のようなことがよくあります。

class MyClass:

    # ...

    def plot(self):
        import someGraphicsLibrary as graphicslib
        graphicslib.plot(self.data)

その理由は、初期化にsomeGraphicsLibraryは時間がかかり、使用するライブラリの1つでは数秒かかるためです。このクラスを使用するときは常に結果をプロットする必要はありません。そのため、実際に使用されるまではインポートしないのが理にかなっています。

これは正常に動作するようですが、他の人のコードでは見たことがないと思います。だから私の質問は、これが良い習慣と考えられるかどうかです。このように物事を行うときに予想される隠れた落とし穴はありますか?


1
これは単にレイジーローディングの一種であり、それほど特別ではありません。
Doc Brown、

1
おそらく少し醜いことを除けば、これを行うことができなかった本当の理由はありません。ライブラリのインポートに時間がかかる場合は、正当な理由があります。私はこれをめったに行わないようにします。ほとんどのインポートがこれほど遅くなることはありません。
Neil

@DocBrownそれが特別であると言っているのではなく、Pythonで特に良い/悪い習慣と見なされているかどうかを尋ねるだけです。
ナサニエル

@Nathaniel:多くの開発者の間で絶対的な「ベストプラクティス」の存在を信じている迷信的な信念があるようです-これはIMHOのナンセンスであり、「プラクティス」には長所と短所があり、何が良いか悪いかは特定のものでしか評価できません環境。上記の例は私には理にかなっているように見えますが、それは単純明快であり、唯一の本当の欠点は、モジュールのすべての依存関係を一目で確認することが難しくなることです(これはKevinの回答のポイント3です)。したがって、パフォーマンスの改善が面倒な価値があると考える場合、この方法は適切です。そうでない場合、この方法は悪いです。
Doc Brown、

回答:


9

これは、いくつかの理由により、通常は良い方法ではありません。

  1. ほとんどの場合、メソッドは高速ですが、最初に呼び出すときは遅くなります。これは、起動時のインポートよりも予測がはるかに困難です。
  2. いくつかの理由でインポートが失敗した場合、実行時にメソッドを呼び出すまで、そのことがわかりません。
  3. ファイルの先頭にリストされていないため、モジュールがどのモジュールに依存しているかを確認することは困難です。
  4. モジュールが文字通りインポートに「数秒」かかる場合、インポート時のロジックで実行していることが多すぎる可能性があります。インポート時のロジックは、通常、モジュールを使用可能にするのに「十分」なだけでなく、重いグローバルオブジェクトの作成を回避する必要があります。このようなオブジェクトが必要な場合がありますが、慎重に調べる必要があります。

ただし、これは良いアイデアである場合があります。次に例を示します。

  1. 配列のようなを実装する場合numpy__array__()メソッドでを使用する必要がある場合があります。ただしnumpy、モジュールの他の機能に依存したくない場合があるため、不要なときに余分な依存関係が発生しないように、numpy内部にインポートすることをお勧めします__array__()。これは、numpy以前に一度インポートされているため(__array__()最初から呼び出されていることです)、問題1と2の影響を受けませんnumpy。また、モジュールの「実際の」依存関係ではないため、問題3の影響を受けません。
  2. PEP 553以前は、ブレークポイントは伝統的に次のようになっていますimport pdb; pdb.set_trace()import pdbブレークポイントは削除される一時的なコード行であるため、モジュールの先頭に配置する必要はありません。インポートを遠くに移動すると、必要以上に難しくなります。これは組み込みbreakpoint()が追加されたときに廃止されたため、インラインインポートは必要ありません。

4
OPによって投稿された例が、回答の「Good idea#1」のケースに当てはまる例のように見えることを言及するのを忘れていました。それは、プロットから独立し、グラフィックスライブラリなしで使用できるコア機能を持つクラスまたはモジュールのように見えます。
Doc Brown、

@DocBrown:MyClassは意味のある名詞ではないので、結論に飛びついていると思います。
ケビン

まあ、私は完全に投稿を読むのに時間をかけました。多分私はいくつかの推測をしましたが、OPがそれについてどう思うかを見てみましょう(そして私を誤解しないでください、あなたの答えはすでに私から賛成票を得ています)。
Doc Brown、

@Kevin Doc Brownの最初のコメントは私の投稿の正しい解釈です。(+1、これは役立つ回答です。)
ナサニエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.