2024年09月12日(木) [長年日記]
■ [python] Pythonのモジュールとパッケージ
Pythonの「モジュール」と「パッケージ」という用語の使い分けがよくわからなくなる。
pipでインストールしているものはモジュールなのかパッケージなのか?importしているものはモジュールなのかパッケージなのか?
定義
Pythonの用語集には次のように書かれている。
(モジュール) Python コードの組織単位としてはたらくオブジェクトです。モジュールは任意の Python オブジェクトを含む名前空間を持ちます。モジュールは importing の処理によって Python に読み込まれます。
パッケージ を参照してください。
(パッケージ) サブモジュールや再帰的にサブパッケージを含むことの出来る module のことです。専門的には、パッケージは __path__ 属性を持つ Python オブジェクトです。
regular package と namespace package を参照してください。
パッケージの説明に「__path__ 属性を持つ Python オブジェクトです」とあるけど、英語版には「a package is a Python module with a __path__ attribute.」とある。つまり、
- __path__ 属性を持つモジュールのことを特別にパッケージと呼ぶ
と考えればよさそう。では、__path__ 属性とは何か?
__path__ 属性
__path__ 属性については次に説明があった。
パッケージの __path__ 属性は、そのサブパッケージのインポート中に使われます。インポート機構の内部では、それは sys.path とほとんど同じように機能します。つまり、インポート中にモジュールを探す場所のリストを提供します。しかし、一般的に __path__ は sys.path よりも制約が強いです。
この説明からわかるのは、__path__ 属性はモジュールのインポート処理に使うためのものだということ。
__path__ 属性の有無を調べてみる。
% python Python 3.12.6 (main, Sep 12 2024, 17:06:52) [GCC 11.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import os, json >>> hasattr(os, "__path__") False >>> hasattr(json, "__path__") True >>>
osモジュールはパッケージではないが、jsonモジュールはパッケージであることがわかる。
配布パッケージとインポートパッケージ
上述したことから、importしているものはモジュールだということになるだろう。
一方、pipでインストールするものはパッケージと呼ばれている気がする。
どうやら、Pythonのパッケージという用語には二種類あると考えるべきなようで、Python Packaging User Guideの次のページで説明がなされていた。
これを読むと、先に調べたPythonのパッケージは詳しくは「インポートパッケージ」であり、pipでインストールするものは「配布パッケージ」であると考えるようだ。
パッケージという言葉はあいまいなので、使い方に注意が必要そう。次の言明は正しいと言えるだろうか。
「NumPyという配布パッケージをインストールすると、numpyというモジュールをインポートできるようになる」