【Python】モジュールとパッケージ — Python入門

Pythonプログラムを作るときに、標準ライブラリやサードパーティ製のモジュールなどの利用は必須です。この記事ではモジュールをインポートする方法、モジュールやパッケージ全般について解説します。

この記事で主にわかること
  • モジュールをインポートするimport文の使い方
  • モジュールの作り方
  • モジュールをパッケージにまとめる方法
目次

モジュールのインポート

ここでは標準ライブラリやサードパーティ製のモジュールをインポートして、自分のプログラムで利用する方法を説明ます。

モジュールのインポート — import文

モジュールを利用するには、import文を使ってジュールをインポートする必要があります。最も単純なimport文の使い方は次のような構文です。

import モジュール名

試しにPython標準ライブラリのmathモジュールをインポートして使ってみましょう。

>>> import math

import文が実行されるとモジュールのコードが読み込まれ(実行され)、モジュールの名前(この例ではmath)は、実行されたコンテキストの名前空間に取り込まれます。これはモジュールの名前が、そのコンテキストで使えるようになるということを意味します。

モジュールの名前がコンテキストの名前空間に取り込まれると、その名前を使ってモジュールで定義された関数や変数を参照することができます。具体的には「モジュール名.関数名」や「モジュール名.変数名」のようにドット(.)で繋いで参照します。これはドットを使ってオブジェクトの属性を参照する方法と同じです。実際、モジュールで定義された関数や変数はモジュールの属性なのです。

次の例は「モジュール名.関数名」で、mathモジュールで定義されたfloor関数を呼び出しています。

>>> math.floor(3.14)
3

import文はどこにでも書くことができますが、プログラムの先頭ですべてのimport文を記述することが推奨されています。

モジュールの属性を直接インポートする

先ほどのインポートでは、モジュールの属性(関数や変数など)にアクセスするには「モジュール名.名前」というようにモジュール名を通して参照する必要がありましたが、モジュールの属性(関数や変数など)の名前を直接インポートすることもできます。構文は次の通りです。

from モジュール名 import 名前

このようにインポートすると、実行したコンテキストの名前空間にモジュールの関数などの名前が直接取り込まれます。そのため直接その名前をコードで使うことができます。

>>> from math import floor
>>> floor(3.14)
3

インポートする名前はカンマで区切って複数指定することもできます。

>>> from math import floor, ceil
>>> floor(3.14)
3
>>> ceil(3.14)
4

もちろん、これは複数行でインポートしても構いません。

>>> from math import floor
>>> from math import ceil

アスタリスク(*)を使って、名前をまとめてインポートすることもできます。ただし、これはほとんど使われません。アスタリスクを使うと、インポートされる名前の把握も困難で、名前が衝突するかも知れません。コード作成者が何をインポートしたいのか、その意図も伝わらないので、コードの可読性も低下します。

from math import *

別名を付けてインポートする

インポートする名前に別名を付けることもできます。それにはimport文の末尾で「as」に続けて別名を指定します。

import numpy as np

このようにすると、プログラムの中で別名を使うことができます。この例ではNumPyというモジュールを読み込んで、npという別名を付けています。

NumPyはサードパーティ製のモジュールなので、インポートする前にpipでインストールする必要があります。

次の例は別名(np)を使ってarange()関数を参照しています。

>>> np.arange(3)
array([0, 1, 2])

適切な別名を付けると、タイプ量を減らしコードも分かりやすくなります。numpyにはnpという別名を付けるのが一般的な慣習です。このようにモジュールによっては慣習的に使われる別名があります。

なお、fromを使ったインポートでも別名を付けることができます。

モジュールの作成

Pythonのプログラムが大きくなってくると、管理しやすいようにプログラムを複数のファイルに分割したくなるかもしれません。また、他のプログラムでも使える有用なコードは再利用したいと思うでしょう。

これまで標準ライブラリなどのモジュールをインポートして利用してきましたが、モジュールは自分で作成することもできます。それには次のようなルールにしたがってファイルにコードを記述するだけです。

  • リスト
  • リスト
  • リスト

Pythonのコードは「.py」の拡張子でファイルに保存しておくだけで、他のプログラムから利用することができます。単に、他のプログラムから利用される目的で作成されたPythonファイルがモジュールと呼ばれます。

モジュールのファイル名は「モジュール名.py」とする必要があります。モジュール名として使用できる文字は、変数名と同じルールがあります。

モジュールにある関数や変数のような定義は前述の例と同様に、他のモジュールやメインプログラムからインポートして利用できます。モジュールには、関数などの定義の他に実行文を入れることもできます。実行文は、通常モジュールを初期化するためのものです。これらの実行文は、import文でモジュールがインポートされたときに一度だけ実行されます。

試しに簡単なモジュールを作成してみましょう。以下のコードを「mymodule.py」というファイル名で、現在のディレクトリに保存します。

import math

print('Module start')

foo = 'foo string'

def floor_and_ceil(val):
    return math.floor(val), math.ceil(val)

print('Module end')

対話型インタプリタから、このモジュールを利用してみましょう。

>>> import mymodule
Module start
Module end

モジュールはインポートされた時点で、モジュール全体が実行されます。これはモジュールの先頭と末尾のprint()関数が実行されていることからもわかります。

モジュールの属性にもアクセスしてみましょう。

>>> mymodule.foo
'foo string'
>>> mymodule.floor_and_ceil(3.14)
(3, 4)

各モジュールはモジュール独自の名前空間を持っています。その名前空間はモジュールがインポートされたときに作成されます。そしてモジュールで定義されている関数や変数などの名前はこの名前空間に置かれます。名前は独自の名前空間に置かれるので、他のモジュールとの名前の衝突を気にする必要はありません。

いくつかのモジュールの属性はPythonによって初期化され、その名前はこの名前空間に置かれます。その一つに__name__属性があり、これにはモジュール名が入っています。

>>> mymodule.__name__
'mymodule'

モジュールをメインプログラムとして実行する

モジュールは単なるPythonのコードなので、プログラムとして実行することもできます。

python mymodule.py

このようにメインプログラムとして実行すると、__name__ に __main__ が設定されることを除き、import したときと同じようにモジュール内のコードが実行されます。

__name__ に __main__ が設定されることを利用し、メインプログラムとして実行されたときにだけに実行されるコードをモジュールに追加することができます。

これをテストする簡単なプログラムを書いてみましょう。次のコードをmymodule2.pyという名前で保存しましょう。

print(f'__name__: {__name__}')

if __name__ == '__main__':
    print('Main program')

これを対話型インタプリタでモジュールとして利用した場合と、メインプログラムとして実行した場合の出力を比べてみましょう。

# モジュールとして利用
>>> import mymodule2
__name__: mymodule2

# メインプログラムとして実行
$ python3 mymodule2.py
__name__: __main__
Main program

モジュールとしてインポートされたときと、メインプログラムとして実行されたときで、__name__の値の違いに注目してください。また、メインプログラムと実行したときにだけ、if文のブロックが実行されていることがわかるでしょう。 

if文のブロックには、モジュールのテストコードを記述し、モジュールのテストを行うなどの用途があります。

パッケージ

モジュールの数が多くなってくると、それらをグループにまとめ管理したいと思うでしょう。Pythonではモジュールを階層構造に分類してまとめるパッケージと呼ばれる仕組みが用意されています。

バッケージの実体は、 モジュールのファイルを納めたディレクトリです。パッケージとなるディレクトリには、__init__.py という名前のファイルを配置します。__init__.py は空で構いません。初期化用のコードを書くこともできます(詳しい説明は省きます)。

以下にパッケージのサンプルを示します。ディレクトリ名がパッケージの名前になります。animalsはトップレベルのパッケージです。その下にmamals、birds、fishという3つのサブパッケージがあり、その中にモジュールのファイルが置かれています。

animals/
    __init__.py
    mammals/
        __init__.py
        dog.py
        cat.py
    birds/
        __init__.py
        hawk.py
        crow.py
    fish/
        __init__.py
        tuna.py
        salmon.py

すべてのモジュールファイルは、以下の変数のみ定義します。

myname = __name__

このようにパッケージにまとめられたモジュールを実際に使ってみましょう。animalsの親ディレクトリへ移動して対話型インタプリタを起動します。

dogモジュールをインポートします。パッケージの階層構造はドット(.)でつなげます。

>>> import animals.mammals.dog
>>> animals.mammals.dog.myname
'animals.mammals.dog'

fromを使って次のようにインポートすることもできます。

>>> from animals.birds import crow
>>> crow.myname
'animals.birds.crow'

変数は関数の名前を直接インポートすることもできます。

>>> from animals.fish.tuna import myname
>>> myname
'animals.fish.tuna'

モジュール検索パス

Pythonはインポートするモジュールやトップレベルのパッケージをどのように見つけるのでしょうか?Pythonはインポートする際に、sys.path(sysモジュールのpath変数)に格納されたディレクトリやZIPファイルを順に検索して、最初に見つけたものをインポートします。

sys.pathは一般に次のように初期化されます。

  1. Pythonプログラム(pythonインタプリタに渡すファイル)のあるディレクトリ。あるいは対話型インタプリタを起動した場合はカレントディレクトリ(空文字列で示される)。
  2. 環境変数PYTHONPATHに設定されているディレクトリ。PYTHONPATHは環境変数PATHと同じ形式で設定できる。環境変数PYTHONPATHがない場合は何も設定されない。
  3. 標準ライブラリのディレクトリなど。このディレクトリは環境によって異なる。
  4. 追加モジュールが置かれるディレクトリ。一般に標準ライブラリのディレクトリにある「site-packages」ディレクトリ。

sys.pathにはこの順序でディレクトリ(やZIPファイル)が一覧されるので、標準ライブラリと同じ名前のモジュールがカレントディレクトリなどに置かれていると、標準ライブラリのモジュールがインポートされることはありません。

おわりに

実際にimport文を使う際に気をつけたい点について少し追記します。

インポートする方法はいくつか選択することができますが、後でコードを読む人に意図が伝わるようなインポート方法を選ぶようにしましょう。特にアスタリスク(*)を使ったインポートやモジュールの関数などの名前を直接インポートすることは、理解しづらいコードになる恐れがあります。また、名前が衝突するとさらに難解になるので気をつけましょう。

では、最後までご覧いただき誠にありがとうございます。

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

・PM、SE、SIなどを20年以上経験
・ネットワークスペシャリスト、セキュリティスペシャリストなど複数の資格を保有

目次