ユーニックス総合研究所

  • home
  • archives
  • python-main

Pythonのmain関数の書き方をわかりやすく解説

  • 作成日: 2021-06-25
  • 更新日: 2023-12-24
  • カテゴリ: Python

Pythonの`main`関数の書き方

Pythonはスクリプトなのでmain関数を定義する必要はありません。
ありませんが、慣例的にmain関数を定義することがあります。

結論から言うとPythonでmain関数を定義するには↓のようにします。

import sys  


def main(argv):  
    print('Hello, World!')  
    return 0  


if __name__ == '__main__':  
    sys.exit(main(sys.argv))  

この記事ではPythonによるmain関数の定義方法とその関連について解説します。
具体的には↓を見ていきます。

  • main関数とは?
  • main関数の書き方
  • if __name__ == '__main__'について
  • sys.exit()によるプログラムの終了
  • sys.argvを引数として渡す

`main`関数とは?

main関数とはC/C++系の言語で登場する関数です。
たとえばC言語では、プログラムを作る時にこの関数を1つ定義する必要があります。
プログラム開始時に最初に呼ばれる関数がこのmain関数です。

C言語ではmain関数は以下のように定義されます。

int main(int argc, char *argv[]) {  
    // ここに処理  
    return 0;  
}  

main関数はCから派生した言語でも取り入れられている概念です。
たとえばC++でもmain関数が必要です。

いっぽう、スクリプト系言語、たとえばPythonやRubyではこういったmain関数は定義しなくてもスクリプトを実行することができます。
しかし例えばPythonの実装としてはCPythonというのがあり、これはC言語で書かれています。
ですのでPythonの奥深いところではmain関数が実行されているということになります。
もっともPython利用者はそのmain関数の存在を意識する必要はありません。

興味がある方はGitHubでCPythonの実装のソースコードを掘ってみてください。
GitHub - python/cpython: The Python programming language

`main`関数の書き方

Pythonでは関数は↓のように書きます。

def 関数名(引数):  
    処理  

defというキーワードのあとに関数名を書いて、括弧を作って引数を書きます。
そしてコロンで改行してインデントを入れてその中に処理を書きます。

main関数を定義する場合は↓のようなコードになります。

def main():  
    pass  

↑のmain関数は最も基本的なmain関数です。
引数無し、返り値無し、と言う具合です。

引数を取る場合はこれが↓になります。

def main(argv):  
    pass  

さらに返り値(ステータスコード)を返す場合は↓のようになります。

def main(argv):  
    return 0  

目的によってmain関数の定義は使い分ける必要があります。
引数と返り値が存在するバージョンはもっともC言語などのmain関数に近い例です。

`if __name__ == '__main__'`について

端末からスクリプトを実行したときにのみTrueになるif文が↓のようなif文です。

if __name__ == '__main__':  
    print('True')  

たとえばifmain.pyというスクリプトが存在していて、その中身に↑のコードが書かれていたとします。
端末からifmain.pyを実行すると↓のような結果になります。

$ python ifmain.py  
True  

このifmainは他のモジュールからインポートされた場合、↑のif文の中のコード(print('True'))は実行されません。

import ifmain  

グローバル変数の__name__の値は、スクリプトが端末から実行されたときにのみ__main__という値になります。
そのためこれを利用して↑のように端末から実行する場合と他モジュールからインポートする場合とで振る舞いを変更することができます。
これが必要となるケースですが、たとえばモジュールをスクリプトとして実行させたい場合にif文の中にスクリプト用のコードを書いておけば、そのモジュールをスクリプトとしても活用できることになります。

`sys.exit()`によるプログラムの終了

sysモジュールのexit()関数はプログラムを引数の終了ステータスで終了させます。
これを利用して、main関数から返り値を返すようにすれば、その値を終了ステータスとしてプログラムを終了させることができます。

import sys  


def main():  
    return 0  


if __name__ == '__main__':  
    sys.exit(main())  

終了ステータスは0が正常終了で、0以外が異常終了です。
C言語などではこの値は定数としても定義されていて、それぞれ正常終了がEXIT_SUCCESS、異常終了がEXIT_FAILUREと命名されています。
この定数はPythonには存在しないようです。

🦝 < 定数はないんよ

`sys.argv`を引数として渡す

sysモジュールのargv属性にはコマンドライン引数がリストとして格納されています。
このsys.argvmain()関数に渡すようにすれば、よりmain()関数っぽくなります。

import sys  


def main(argv):  
    return 0  


if __name__ == '__main__':  
    sys.exit(main(sys.argv))  

sys.argvの0番目の要素にはプログラムのパスが保存されます。
1番目の要素以降にはプログラムの呼び出し時に渡される引数が保存されます。
たとえば↓のようなテスト用のスクリプトを作ります。

import sys  


print(sys.argv)  

↑のスクリプトを↓のように実行するとsys.argvの中身がどんな風に変化するかわかります。

$ python testargv.py  
['testargv.py']  

$ python testargv.py 1 2 3  
['testargv.py', '1', '2', '3']  

`main`関数のバリエーション

main関数のバリエーションを確認してみます。

基本的な`main`関数

基本的なmain関数は↓のようになります。

def main():  
    pass  


if __name__ == '__main__':  
    main()  

返り値無し、引数無しのもっとも基本的なmain関数です。

終了ステータスを返す`main`関数

終了ステータスを返すmain関数は↓のようになります。

import sys  


def main():  
    return 0  


if __name__ == '__main__':  
    sys.exit(main())  

終了ステータス、引数有りの`main`関数

終了ステータスを返し、コマンドライン引数を受け取るmain関数は↓のようになります。

import sys  


def main(argv):  
    return 0  


if __name__ == '__main__':  
    sys.exit(main(sys.argv))  

おわりに

今回はPythonのmain関数について見てみました。
Pythonにはmain関数は必要ありませんが、あるとなんだかホッとしますよね。

🦝 < C/C++出身者は特にね

🐭 < mainがいなきゃ始まらない