モジュール、パッケージ、ライブラリのまとめ【Python】

programming Python

Python のモジュール、パッケージ、ライブラリについてまとめておきます。加えて、Python を動かしてモジュール等がどのように読み込まれるのか確認しておくことにします。

以下の環境で動作確認をしています。
環境: Windows パソコン、Anaconda、Python 3.x

背景 ~ モジュール、パッケージ、ライブラリとは何か

Python でプログラミングをする際、よく、モジュール、パッケージ、ライブラリといった表現が出てきます。

紛らわしい表現ですので、定義やリンクなどをまとめておくことにします。

加えて、これまでこのサイトでは、Python のサンプルスクリプトをまとめ、公開してきています。これらのサンプルでは、モジュールやパッケージを天下り式にインポートして使っていました。
そこで、よく使っているパッケージ等について、スクリプト(….pyファイル)、フォルダ構成、クラスなどがどのようになっているのか、実際に Python を動かして確認しておくことにします。
とくに、機械学習などをやろうとするとライブラリがややこしくなりますので、ポイントを整理しておきます。

各用語の定義を確認してみる

以下、Python のドキュメントを参照し、概要をまとめておくことにします。
正確な翻訳を意図するものではありませんので、詳しい内容については、リンク先や文献を参照してください。

モジュールとは

・ https://docs.python.org/3/glossary.html#term-module

厳密な翻訳ではありませんが、「モジュールとは、Python コードの1つの構成ユニットとして機能するものをいう。モジュールはインポートのプロセスによって Python に読み込まれる。」(★1)といった程度の記載となっています。

import で読み込むことができる1つの単位、となっていますので、モジュールの例としては、Python のスクリプト(テキストで書かれた、”….py” ファイル)があります。
スクリプトの冒頭などに、”import <module>” と書かれた行があったとき、<module> 部分がモジュールということになります。

なお、Python では、「標準モジュール」として、os モジュール、math モジュールなどがありました。
スクリプトの冒頭などで、”import os”、”import math” 等を実行することで、これらのモジュールを読み込んで、使うことが可能です。

パッケージとは

・ https://docs.python.org/3/glossary.html#term-package

「パッケージとは、Python のモジュールの1つであって、複数のサブモジュールや、再帰的に複数のサブパッケージを含むことができるものをいう。技術的には、_ _path_ _ 属性を持った Python のモジュールのことをいう。」(★2)といった内容になっています。
(サイトの表示上、アンダースコア _ 2つの間にスペースを入れています。実際には2つのアンダースコア間のスペースは削除して理解してください。)

(ファイルの属性というよりは)パスの属性を持ったものであって、複数のサブモジュール(submodules)等を含むことができるもの、となっています。
したがって、パッケージの例としては、Python のスクリプトが複数入ったフォルダ(ディレクトリ)が挙げられます。

なお、パッケージも前述のモジュールの1つと読める記載になっています。
確かに、”import + <フォルダ名>” とすることで、フォルダごとインポートすることも可能になっています。これについては、以下で動作確認をしてみます。

ライブラリとは

ライブラリ library に関しては、Python 公式サイトの glossary では、定義が見つからないようです。(2022年11月時点で。)
・ https://docs.python.org/3/glossary.html

そこで、Python のドキュメントで「ライブラリ」といった表現を探すと、「標準ライブラリ」が見つかります。この記載から、標準ライブラリと標準ではないライブラリ(外部ライブラリ)とがあることがわかります。
・ Python 標準ライブラリ — Python 3.11.0b5 ドキュメント

ライブラリによって、例えばC言語で書かれたモジュールを使うことで直接 Python 言語では実現できない機能についても拡張が可能となる。また、よく使われる機能については Python で書かれたモジュールを活用することで標準化が可能になる、といった概要になっています。
標準ライブラリのリストを見ると、所定の機能を実現するための、組み込み関数・定数・型、クラスなどの一式が挙げられています。
手元にある Python の書籍を参照すると、「Pandas ライブラリは標準ライブラリにはないため、import panda としてロードして使う」といった旨の記載が見つかります。

ライブラリの明確な定義は見つかりませんが、これらの記載から、ライブラリは、モジュールやパッケージを含む概念であって、Python から呼び出すことのできる、拡張性のあるファイルや機能の一式といった程度の理解でよさそうです。

なお、インストールした Python のフォルダ構成を確認すると、「ライブラリ」用のフォルダ(”C:\\…\\Anaconda3\\lib\\”)が設定されています。
このフォルダ階層の下に、モジュールに対応する “os.py” 等のスクリプト一式や、パッケージに対応する “pandas”, “numpy” 等のフォルダ(”lib\\site-packages”フォルダ内)が入っています。
やはり、ライブラリは、これらを総称するもの、と考えられます。

Python を動かして確認してみる

モジュールについて確認をしてみる

つぎに、Python を実際に動かして、モジュール、パッケージ等について確認してみます。
このような場合、スクリプトを作るよりは、対話モードを使ったほうが早いです。
一例として、上記の os モジュール(標準モジュール)について、確認してみます。手元に Python が使える環境のある方は、動かしてみてください。

対話モードで確認する手順 

① コマンドプロンプト(Anaconda を使っている場合は、Anaconda Prompt)を起動する。
② python + [enter] と入力する。
→ python の対話モードが起動する。
③ print( os ) と入力する。
→ エラー “NameError: name ‘os’ is not defined” が表示される。
④ import os と入力する。
⑤ print( os ) と入力する。
→ ”<module ‘os’ from ‘C:\\…\\Anaconda3\\lib\\os.py‘>” と出力される。
⑥ exit() と入力する。
→ Python の対話モードが終了する。

※ ⑤の出力から、”import os” の “os” の実体は、”os.py” ファイルであることがわかります。
Python で “import os” を実行すると、”os.py” ファイルが読み込まれるということがわかります。また、”os.py” の “os” 部分がモジュール名( module ‘os’ from … )として扱われていることが確認できます。

print( <モジュール名> ) を実行することで、モジュールのありか(パス)についても確認できます。

続いて、math モジュールについても確認しておきます。
なお、以降、Python の対話モードを起動・終了する部分は省略して記載します。

ビルトインされている標準モジュールの確認
① Python の対話モードに入り、”print( math )” と入力する。
→ エラーが出る。
② ”import math” を実行し、”print( math )” と入力する。
→ ”<module ‘math’ (built-in)>” と表示される。

※ math モジュールは、os モジュールとは異なり、ビルトイン built-in タイプのモジュールであることがわかります。
つまり、math モジュールの場合は、テキストファイルである math.py を読み込むのではなく、Python の内部にビルトインされた math モジュールを読み込むことで import できるようになっています。

改めて、上記の★1を確認すると、モジュールは、Python のスクリプト(….py)に限定するといった記載にはなっていません。
テキストであろうがビルトインであろうが、モジュールは、import <module> として読み込めるものということになります。
モジュールとは何かについてネット検索をすると、「モジュールは Python のスクリプト(….py)である」といった旨の説明がヒットしますが、正確ではないことがわかります。(….py のスクリプトがなく、built-in タイプのモジュールもあるため。)

ここまでをまとめると、標準モジュールには、Python スクリプト(….py というファイル)を読み込んで機能するものと、ビルトインとなっていてインポートすると機能するもの、があることになります。

パッケージについて確認してみる

続いて、個々のパッケージについても確認をしてみます。

パッケージの確認手順
① Python の対話モードに入り、”print( pandas )” と入力する。
→ ”NameError: name ‘pandas’ is not defined” と表示される。
② ”import pandas” を実行し、”print( pandas )” と入力する。
→ ”<module ‘pandas’ from ‘C:\\…\\Anaconda3\\lib\\site-packages\\pandas\\_ _init_ _.py’>” と出力される。

※ パッケージの場合、Python のスクリプト “_ _init_ _.py” が入っているフォルダ(ディレクトリ)が実体であることがわかります。また、”_ _init_ _.py” が入ったフォルダのフォルダ名(path 属性を持ったもの)が、”モジュール名” として扱われています。また、Python のプログラムを動かしている限りは、パッケージ package という単語は、出てこないことがわかります。

つまり、”import pandas” を実行すると、Python のプログラムは、”_ _init_ _.py” が入っている “pandas” フォルダを探してきて、このフォルダに入っている(複数の)モジュールを読み込む動きになっています。
加えて、モジュールはインポートできるものとなっていましたので、パッケージ “pandas” (フォルダ)をインポートしてみると、モジュールとして表示(module ‘pandas’)されています。

モジュールは、Python のスクリプト(….py)や、ビルトインされている機能に加え、パッケージ(モジュールが複数入ったフォルダ)をも含むことになります。

パッケージ(フォルダ)かどうかの確認
上記の手順を使って、import してよく使われるモジュールについて、パッケージか否かを調べていくと、以下となっています。
・ os、glob は、Python のスクリプト os.py、glob.py を読み込んでいます。モジュールではありますが、パッケージ(path 属性、フォルダ)には該当しないことがわかります。
・ joblib、matplotlib、numpy、pandas、pygame、sklearn、tensorflow、tkinter は、フォルダを読み込んでいます。モジュールであって、かつ、パッケージ(path 属性)にも該当することがわかります。

パッケージ一覧を確認してみる ~ パッケージと pip list 等の関係

つぎに、パッケージ一覧を確認してみます。

① コマンドプロンプト(Anaconda を使っている場合は、Anaconda Prompt)を起動する。
② ”pip list” + [enter] と入力する。
→ pip コマンドでインストールしたパッケージの一覧が表示されます。
③ Anaconda を使っている場合は、”conda list” + [enter] と入力する。
→ Anaconda でインストールしたパッケージの一覧が表示されます。

※ 出力される表示を確認すると、前述の Python の対話モードで確認したパッケージ joblib、matplotlib、numpy、pandas、pygame、sklearn、tensorflow などがパッケージ一覧にあることを確認できます。tkinter は tk と表示されています。

これらの実体は、ファイルを含むフォルダ(≒パッケージ)であって、pip インストールなどにより、Python のライブラリ(標準ライブラリ、外部ライブラリ)として追加されていることがわかります。
一方、パッケージに該当していない os モジュール、math モジュール(フォルダではなく、os.py などとなっているもの)については、リストには出力されていない、といった動きになっています。

import matplotlib.pyplot とは、どういうことか

Python のスクリプトをいくつか見ていくと、つぎのようなインポート文が記載されていることがあります。
import matplotlib.pyplot

上記について調べてみます。
Python の対話モードで、”import matplotlib.pyplot” を実行し、”print( matplotlib.pyplot )” としてみると、以下の出力が得られます。
“<module ‘matplotlib.pyplot’ from ‘C:\\…\\lib\\site-packages\\matplotlib\\pyplot.py’>”

つまり、“import matplotlib.pyplot” は、”matplotlib” フォルダ(ディレクトリ)内にある “pyplot.py” ファイルを指定して読み込んでいることがわかります。
加えて、import 文においては、ドット “.” は、単に、フォルダやファイルの階層関係を示す意味で使われていることがわかります。(この事例の場合、メソッドを呼び出しているわけではありません。)

また、この状態で、”print( pyplot )” を実行するとエラーが出ることから、モジュール名は、”pyplot” ではなく、”matplotlib.pyplot” であることがわかります。
このモジュール名 “matplotlib.pyplot” で、Python のプログラムに読み込まれ、以後、スクリプト内で使えるようになっていることがわかります。

from datetime import date とは、どういうことか

Python のインポート文を確認すると、以下のような記載も見られます。
from datetime import date

上記と同様に、確認をしてみます。
Python の対話モードを起動し、”from datetime import date” として、”print( date )” を実行すると、以下の応答となります。
“<class ‘datetime.date’>”
今度は、”<module … >” とはなっていません。”datetime.date” は、モジュールではなくクラスであることがわかります。つまり、import 文によってクラス “date” が呼び出されていることがわかります。

そこで、”import datetime”、”print( datetime )” を順次実行すると、つぎの応答が得られます。
“<module ‘datetime’ from ‘C:\\…\\lib\\datetime.py’>”

つまり、datetime の実体は datetime.py という Python スクリプトであることがわかります。
すると、from <….py> import <class 名> とすることで、datetime.py (<….py>)のスクリプトの内部を参照し、クラス “date”(<class 名>)を見つけ、そのクラスをインポートしている、ということがわかります。

上記の定義と動作から、モジュールは、インポートできるものですが、インポートできるものがすべてモジュールではないことがわかります。
スクリプト ….py や、ビルトインモジュール、フォルダ以外であっても、クラスについてもインポートできるようになっているからです。
クラスをインポートする場合、どのスクリプトに書かれているのか指定する必要があるので、from <ファイル名> import <クラス名> としていることがわかります。

以上は、Python のファイルを指定して、スクリプトに書かれているクラスを読み込む事例となっています。

機械学習のインポート文を確認してみる

つぎに、機械学習関連(sklearn など)のスクリプトでのインポート文についても確認してみます。
よく使われるランダムフォレストのインポート文の一例を挙げると、以下があります。
from sklearn.ensemble import RandomForestClassifier

最も複雑そうなインポート文の事例を抜き出しました。一見すると意味不明です。
そこでまず、Python の対話モードを起動し、いったん “import sklearn” を実行し、”print( sklearn )” としてみます。
すると、”C:\\…\lib\\site-packages\\sklearn\\…” と出力されることから、”sklearn” の実体はフォルダであることがわかります。
このフォルダの中を確認すると、”ensemble” というフォルダ(パッケージ)が入っています。
フォルダ “ensemble” 内にある “_ _init_ _.py” をテキストエディタで開いてみます。
すると、RandomForestClassifier は、”_forest.py” で定義されていることがわかります。
そこで、”ensemble” フォルダ内にある “_forest.py” をテキストエディタで開いてみると、RandomForestClassifier が定義されており、クラスであることがわかります。

したがって、from sklearn.ensemble import RandomForestClassifier を実行すると、Python は、まず、フォルダ “sklearn.ensemble” 内の “_ _init_ _.py” ファイルを参照します。
すると、”_forest.py” に RandomForestClassifier が定義されていることがわかるため、”_forest.py” にアクセスし、RandomForestClassifier というクラスをプログラムに読み込んでいる
、ということがわかります。

この状態で、”print( RandomForestClassifier )” を実行してみると、以下の応答が返ってきます。
“<class ‘sklearn.ensemble._forest.RandomForestClassifier’>”

この応答の読解を試みるとすると、つぎのようになります。
フォルダ “sklearn” の中にフォルダ “ensemble” があって、フォルダ “ensemble” の中には “_forest.py” というスクリプトがある。このスクリプト “_forest.py” 内に RandomForestClassifier が定義されている。
スクリプトの記載から RandomForestClassifier をクラスとして読み込んだ(RandomForestClassifier というクラスを import した)、ということがわかります。
ドット “.” が3つ使われていますが、前半の2つの “.” はフォルダやファイルの階層関係を示しています。最後の “.” はファイル内を参照したという意味で使われています。”.” が使われてはいるものの、メソッドを呼び出しているわけではないことがわかります。

Python のスクリプトとしては、インポートを実行することで、ランダムフォレストに関連するクラス RandomForestClassifier が使えるようになっています。

まとめ

Python でプログラミングをしているとよく出てくる、モジュール、パッケージ、ライブラリについてまとめました。

加えて、Python のモジュールやパッケージには機械学習のように複雑なものがありますが、実行時にどのように動いているのか、基本的な部分について動作を確認しました。

Python や機械学習などの書籍を読むと、意味もわからず、いわれるがままにモジュールやパッケージを多数インポートして、とりあえず動いているから、まあ、OK、といったことになりがちです。
モジュール、パッケージなどについて、定義からスタートして、各スクリプト、フォルダ、動作するところまでを確認しておくと、だいぶん、見通しがすっきりするものです。

参照したスクリプトなどを関連リンクに挙げておきますので、もし関心があるようでしたら参照してみてください。

関連リンク
・ 機械学習で株価予測 【Python】
・ 他のスクリプトの関数を実行する 【Python】
・ 関数とメソッドの違い 【Python】
・ “cannot import name ‘joblib’ from ‘sklearn.externals’ “の表示が出たとき 【scikit-learn】
・ すでにインストールされているパッケージを確認する 【Linux】

外部リンク
・ 6. モジュール — Python 3.12.1 ドキュメント

タイトルとURLをコピーしました