mameブログ

mameという男がやりたい事をやっている記録

Pythonで関数、モジュール、パッケージを作成する

■はじめに

以前、C++JPEG画像にフィルタをかける関数プログラムを作成しました。
mame-mame.hatenadiary.com


次の記事では、そのフィルタ関数をスタティックライブラリとして作成しました。
mame-mame.hatenadiary.com


では、Pythonコードではどのようにするのでしょう。
本記事では
Pythonの「関数化&モジュール化」「ライブラリ(パッケージ)化」
について紹介します。

Pythonでの作成方法

本記事におけるサンプル

今回サンプル関数として、四則演算を使用します。
加算関数をadd
除算関数をsub
乗算関数をmul
除算関数をdiv

としました。
この関数を作成して、アプリ側では関数をコールします。

関数化&モジュールの作成方法

要点だけお伝えします。
関数化する際はdefを使います。
C/C++のように変数の型指定が無いため、返り値の型宣言はありません。
一方でC/C++のように引数の設定や帰り値の指定は行います。
指定の方法はC/C++と同様です。
では、四則演算関数を定義します。

def add(x,y):
    result = x + y
    return result

def sub(x,y):
    result = x - y
    return result

def mul(x,y):
    result = x * y
    return result

def div(x,y):
    result = x / y
    return result

SAMPLE_NUM_X = 8
SAMPLE_NUM_Y = 4


SAMPLE_NUM_X、SAMPLE_NUM_Yも宣言しておきました。
以上の記述した内容を、calc_func.pyという名前でファイル保存します。
calc_func.pyは各関数を集めたモジュールとなります。


次にアプリ側。
アプリ側はコールしたいモジュールをimportによって参照します。

import calc_func

if __name__=='__main__':
    a1 = calc_func.add(5,3)
    print(a1)
    a2 = calc_func.sub(4,6)
    print(a2)
    a3 = calc_func.mul(calc_func.SAMPLE_NUM_X, calc_func.SAMPLE_NUM_Y)
    print(a3)
    a4 = calc_func.div(calc_func.SAMPLE_NUM_X, calc_func.SAMPLE_NUM_Y)
    print(a4)


以上の記述した内容を、exec1.pyという名前でファイル保存します。


ターミナルで、アプリを実行すると以下の結果が得られます。
f:id:mizzzo:20200506154747p:plain
四則演算がきちんと実行できています。
乗算・除算は、calc_func.pyモジュールの変数も参照しています。

パッケージの作成方法

パッケージはディレクトリ(フォルダ)によって定義します。
パッケージ内に、モジュールと__init__.pyを置くことによりアプリ側からはパッケージと認識されます。


calc_packageというディレクトリ名でディレクトリ作成します。
ディレクトリ内に、calc_func.pyと、__init__.pyを置きます。
__init__.pyには何も書く必要はありません。
calc_func.pyというファイルには以下を記述します。
(モジュール化の説明と同名ですが、異なる内容を記述します)

def add(x,y):
    result = x + y
    return result

def sub(x,y):
    result = x - y
    return result

def mul(x,y):
    result = x * y
    return result

def div(x,y):
    result = x / y
    return result

SAMPLE_NUM_X = 10
SAMPLE_NUM_Y = 2


次にアプリ側です。
アプリ側はコールしたいパッケージ内及びその中のモジュールをfrom ○○ import ●●によって参照します。

from calc_package import calc_func

if __name__=='__main__':
    a1 = calc_func.add(5,3)
    print(a1)
    a2 = calc_func.sub(4,6)
    print(a2)
    a3 = calc_func.mul(calc_func.SAMPLE_NUM_X, calc_func.SAMPLE_NUM_Y)
    print(a3)
    a4 = calc_func.div(calc_func.SAMPLE_NUM_X, calc_func.SAMPLE_NUM_Y)
    print(a4)


以上の記述した内容を、exec2.pyという名前でファイル保存します。
※1行目以外、exec1.pyとexec2.pyは同じ内容です。


ディレクトリ構成は以下のようになります。
f:id:mizzzo:20200506160415p:plain


ターミナルで、exec2.pyアプリを実行すると以下の結果が得られます。
f:id:mizzzo:20200506160605p:plain
calc_package内に保存したcalc_func.pyを参照している事は、乗算・除算(SAMPLE_NUM_X、SAMPLE_NUM_Yを使用)の結果からも分かります。

if __name__ == "__main__":について

PythonC/C++と異なり、main関数がありません。
その代わり本構文で、モジュールを直接実行する時に、どこから実行するかを定義しています。
直接実行するとは、本記事で示しているようにコマンドラインからPythonアプリを実行する事を指します。
一方でそれ以外の方法としてモジュールをインポートして使用する場合があります。
本構文を使用すると、モジュールをインポートして使用する場合に関数の中身はコールされません。


詳しくは、以下のサイトが参考になります。
techacademy.jp


__init__.pyについて

__init__.pyはアプリがモジュールを検索する時のマーカーとなります。
このファイルがなければ、exec2.pyは実行時エラーが発生します。


詳しくは、以下のサイトが参考になります。
qiita.com

■おわりに

本記事では、モジュール化やパッケージ化を紹介しました。
大規模プロジェクトになってくると、1ファイルではとても整理できなくなってきます。
プロジェクト構成を整理しやすくするために、本記事のようなノウハウは必須になってくるでしょう。