Pythonでの関数定義と関数呼び出し

Pythonでの関数定義と関数呼び出しについて基本的な内容について書きます。
関数とは何かというと数学的な定義とプログラミング的な定義等でややこしくなりそうなので、ここでは実務的なプログラミングの関数として以下のページで書いた意味合いで書きます。
フローチャートと構造化チャート
つまり関数とは構造化プログラミングのブロックという再利用可能な意味のあるまとまった処理の単位ということです。それをPythonでの書き方について確認します。今回は簡単なメイン関数とサブ関数を書きます。ここでの環境はPython3.5.3です。


上のPAD図ではメイン関数があってサブ関数1とサブ関数2があってメイン関数から順番にサブ関数1とサブ関数2が呼ばれる構造です。PAD図は左右上下2次元構造で表現するのでこのような図になります。

私の文章で書いても分かりにくいだけだと思いますので実際にPythonで書きます。

直接起動時のメイン関数

if __name__ == '__main__':
    print("モジュール名:{}".format(__name__)) 
    print("main関数")

上記のif文は(コマンドラインで)直接実行すると__name__変数の中に自動で__main__という値が代入されるので条件が真となります。
実行結果は以下です。print文が実行されています。

それでは、実行されない(真とならない)場合はどういう場合かというとモジュールとして呼び出された場合ですがこのモジュール化については後述します。

サブ関数
PAD図のサブ関数1、サブ関数2を追加で書きます。以下のようになりました。

def subFunc1():
    print("サブ関数1")

def subFunc2():
    print("サブ関数2")

if __name__ == '__main__':
    print("main関数")
    subFunc1()
    subFunc2()                                                       ~                    

実行結果は以下です。PAD図で書いたように順番に呼び出されています。

モジュール分割
以下のようにファイルを分割します。同一ディレクトリに存在しています。
メイン関数 main.py

import sub

if __name__ == '__main__':
    print("main関数")

    sub.subFunc1()
    sub.subFunc2()

サブ関数 sub.py

def subFunc1():
    print("サブ関数1")

def subFunc2():
    print("サブ関数2")

if __name__ == '__main__':
    print("メインコール:{}".format(__name__))

print("モジュールコール:{}".format(__name__))

以下で実行します。
$ python3 main.py

結果は以下です。

プログラムのポイントはメインから import sub でインポートしている点と、sub.subFunc1()という書き方で呼び出している点です。

実行結果のポイントはimport時にsub.pyが実行されている点です。PAD図とは若干違う流れですね。このように実行されるということはモジュール化を考えないで常に実行されるような処理は書かない方がいいということです。

標準ライブラリ等のモジュールの場所
sys.pathで場所の一覧が表示されます。以下が実行例です。

以上、基本的な内容ですが、Pythonでの関数定義と関数呼び出しについて書きました。特にプログラミングを始めた時点では関数分割、モジュール分割を考えないで、1ファイルに全部の処理を描いてしまいがちです。私もそうでしたが早めにモジュール分割(つまり正しい設計)を意識した方がいいです。

「結合度」について少しだけ補足
モジュール設計の指針の一つとして「結合度」という考え方があります。モジュールの分割度として結合度が低いほど好ましいということです。結合度が低いということはモジュール変更の際にほぼそのモジュールのみを変更すればいいということです。逆に結合度が高いとは、モジュール間でどう影響しあっているか分からなくなり変更した場合に意図しない問題が出る場合があるということです。

実際に具体的が書ければいいですが、ここでは以下のWikipediaのリンクだけにしておきます。
結合度