ライブラリを自作する

記事の内容

 この記事では、自分でライブラリモジュールを作成し、別のモジュールからimport文で取り込んで利用する方法について説明します。
 よく利用する便利な関数やクラスをライブラリとして別モジュールにまとめておくことによって、プログラミングの効率を上げることができます。

***わからない用語があるときは索引ページへ***

1.ライブラリとは

 別のモジュールから呼び出して繰り返し利用することを目的としたパッケージやモジュールのことを、ライブラリとよびます。ライブラリの中身は、別モジュールから再利用するための関数、クラス、変数などのオブジェクトで構成されるプログラムです。ライブラリは、別モジュールからオブジェクトの再利用を目的として作成する機会が多いですが、ライブラリの中でプログラムを実行することもできます。
 繰り返し利用できるオブジェクトは、別ファイルにまとめておくと、後で必要なときにいつでも呼び出して利用できるため、プログラム作成が効率的になります。

2.自作のライブラリモジュールを作成する

 ライブラリの作成と読み込み方法についてサンプルプログラムを使って説明します。

2つの定数と関数だけで作ったライブラリのサンプルプログラムです。

##mylib_ex1.py

##定数
PARA1 = 5
PARA2 = 3

##関数
def tashizan(a, b):
   return a + b
def hikizan(a, b):
   return a - b

 ライブラリは、pythonのモジュールなのでファイル名の拡張子は".py"で作成する必要があります。mylib_ex1.pyモジュールは、定数が代入された変数と関数のみで構成されています。関数は呼び出されて初めて実行されるので、mylib_ex1.pyを実行しても何も起こりません。

 つづいて、mylib_ex1をインポートして利用するサンプルプログラムです。

##mylib_imort_ex1.py

##mylib_ex1モジュールをインポート
import mylib_ex1

a = mylib_ex1.PARA1
b = mylib_ex1.PARA2

wa = mylib_ex1.tashizan(a, b)
print("a + b =", wa)

実行結果

a + b = 8

 import文の書式や呼び出しの規則についての詳細は、前の記事を参照してください。

 私が使っているプログラミング環境は、PyDev-Eclipseです。私は原則プロジェクト単位でライブラリ用のパッケージ(フォルダ名は'lib'としている)を作成し、そこにライブラリモジュールを置くようにしています。他のプロジェクトのライブラリを参照したい場合のみ、sys.path.appendメソッドを使ってパスを通すようにしています。sys.pathについての詳細は前の記事を参照ください。

3.if __name__ == '__main__': -他のモジュールからインポートされたときには実行されないプログラムを記述する

 ここまで、「import文はライブラリを自分のプログラムに取り込んで再利用するために作る」と説明してきました。この説明は、ライブラリを作る目的としては正しいのですが、Pythonの動作としては正確な表現ではありません。

 import文でモジュールを取り込むと、Pythonインタープリタはimportしたモジュールを読み込んでそのまま全て実行してしまいます
 したがって、ライブラリとしたいモジュールの中で関数を呼び出して実行するプログラムが書かれている場合、import文でモジュールをインポートすると、関数の呼び出し実行部分も含めて実行されてしまいます。
 それが意図したものであれば問題ありません。しかし、実行可能なモジュールの中で作成した関数やクラスなどのオブジェクトだけをライブラリとして再利用したい場合もあります。
 このような場合は、関数やクラスを呼び出して実行しているプログラムブロックを、「自分がPythonインタープリタで直接実行されているときのみ実行する」という条件をつけて実行するようにします。
 ライブラリモジュールのサンプルプログラムをみてみましょう。

##mylib_ex2.py

##定数
PARA1 = 5
PARA2 = 3

##関数
def tashizan(a, b):
   return a + b

def hikizan(a, b):
   return a - b

##プログラム実行開始位置
if __name__ == '__main__':
   wa = tashizan(PARA1, PARA2)
   sa = hikizan(PARA1, PARA2)
  
   print("a + b =", wa)
   print("a - b =", sa)

実行結果

a + b = 8
a - b = 2

__name__ == '__main__'がTrueであれば、プログラムブロックの中が実行されます。ここで、__name__は特殊変数であり、Pythonインタプリタから直接呼ばれて実行されるときには、'__main__'という文字列がセットされます。
 別モジュールからインポートされて実行される場合は、__name__には自身のモジュール名がセットされます。
 したがって、この条件分岐をつけることにより、モジュールが他のモジュールにimportされた場合は、if文のプログラムブロックは実行されないことになります(__name__ == '__main__'の条件式がFalseになる)。結果、tashizan関数とhikizan関数のみをライブラリとして別モジュールが利用できるようになります。

 モジュールの中で関数やクラスを作成する場合は、必ずこの条件文をつけてC言語のmain関数のような使い方をする人もいるようです。

from <モジュール> imoprt <オブジェクト>

を使って、オブジェクト単位で読み込む場合は、この条件文の有無は動作に影響しません。

また、この条件分岐を書かずに、モジュールがインポートされるときに共通の処理を意図して実行させることもできます。

4.ライブラリのパッケージを自作する

 パッケージとは、1つ以上のモジュールで構成されるプログラムが保存されたフォルダのことです。別のモジュールからパッケージをインストールするためのimport文の書式や呼び出しの規則についての詳細は、前の記事を参照してください。
 パッケージの直下には、必ず

__init__.py

というファイル名のモジュールを置く必要があります
 別のモジュールからパッケージをインポートすると、自動的にこの__init__.pyが実行されます。これは、モジュールをインポートしたときにそのモジュールの中身が実行されるのと同様です。__init__.pyにライブラリとして利用したい関数やクラスを書くと、パッケージをインポートしただけで__init__.pyの関数やクラスを利用することができます。
 パッケージをインポートする際、インタープリタは__init__.pyを参照しに行きますので、必ず作成しなくてはなりません。__init__.pyで処理するものがない場合は、__init__.pyを空ファイルで作成します。

 ライブラリをパッケージとして作成することによって、モジュール単体をライブラリ化する場合と比べ、よりアプリケーションに近いライブラリを作成することができます。ライブラリ内部で使用する外部ライブラリとのバージョン依存関係を管理する、ライブラリの設定ファイルを置く、出力結果を保存するフォルダを作っておく、などです。パッケージはフォルダなので、プログラムファイル以外のファイルもセットで管理することができます。
 次の記事で説明する外部ライブラリは、パッケージとして公開されています。

前の記事 次の記事



この記事が気に入ったらサポートをしてみませんか?