【Python】if __name__ == ’__main__’:ってなに?

今回はPythonプログラムの最後の方にたびたび見かける以下のif構文について解説します。パッケージやライブラリを見てると出てくるんだけど何をしているかわからないし、これ必要なの?という疑問が解消できるように書いていきますね。

if __name__ == '__main__':
    main()

Pythonオフィシャルの日本語訳ドキュメント

まずは、オフィシャルの文書を引用してみます。なんと言ってもオフィシャルですから。そこを押さえておかないと正しい理解ができないかもしれませんから。

‘__main__’はトップレベルのコードが実行されるスコープの名前です。モジュールが、標準入力から読み込まれたとき、スクリプトとして実行されたとき、あるいはインタラクティブプロンプトのとき、__name__には’__main__’が設定されます。
モジュールは、自身の__name__をチェックすることでメインスコープで実行されているかどうかを確認できます。これはモジュールがスクリプトとして、あるいはインポートでなくpython -mで起動されたときに実行するコードの条件として使用できる一般的なイディオムです。

管理人
?トップレベルコーd?いんたらなんたら???(.˙∠)?

あ、あぶない。自分の日本語の偏差値が3ぐらいになったかと錯覚した。さすがオフィシャル攻撃力高い。素人には危なすぎますね。
ちょっとずつ実装しながらこのオフィシャルの文書を要約していきましょう。

変数「__name__」

まずは、このプログラムと引用文からどうやら「__name__」は変数。しかも「_(アンダースコア)」2つに囲まれているので、システムで定義した変数のようです。
つまり、システムが動作する際に、何かしらの値が入ってくるのだろう。そして、以下の一部抜粋部を鑑みるになにかの条件を満たすと『’__main__’』という文字列が代入されると言っているよう。

モジュールが、標準入力から読み込まれたとき、スクリプトとして実行されたとき、あるいはインタラクティブプロンプトのとき、__name__には’__main__’が設定されます。

と言うことで以下のプログラムを実行してみようと思います。

実際に試してみる(『’__main__’』が出る場合)

一旦、何も考えずただただ「__name__」を出力してみることにしましょう。それだけを記述したPythonファイルを作成し、実行してみました。

print(__name__)

まずは、引用文の通り『’__main__’』というものが出力されました。インタラクティブっていうのは手続きという意味だからコンソール(コマンドプロンプト)でやったときにってことかな?こちらもやってみます。

あってるみたいですね。よくわかりませんが、直接プログラムを呼び出したり、手続きでやってるときは『’__main__’』が出るということが予想される。再び一番最初のプログラムを見返しましょう。

if __name__ == '__main__':
    main()

if文を書いているということは、『’__main__’』以外もあり得るということ、ではどうなれば『’__main__’』以外が出るのか?

実際に試してみる(『’__main__’』以外が出る場合)

先程の試行で直接プログラムを呼び出したり、手続きでやってるときは『’__main__’』が出るということが予想したのでそれ以外の場合、例えば別のプログラムから読み込まれた場合はどうなるのか、実際に以下のプログラムを用意して試します。

「module1.py」

print("Yeah")
print(__name__)

def test():
    print("hello Python!")

if __name__ == '__main__'
    test()

print("module1 end")

「module2.py」

import module1

print("Start")
print(__name__)

def test2():
    print("Yes")

if __name__ == '__main__':
    test2()

これで「module1」を実行して、その後「module2」を実行してみると以下の結果を得ることができました。


ここで見るべきはmodule2.pyを起動したときの「print(__name__)」が

『’__main__’』ではなく『’module1’』

となっていることです。これをヒントにすればなんとなく理解できそうですね。ということで結論を出したいと思います。

結論

上で、いろいろ試した結果。このif文は実行したプログラムが、直接呼び出されているか、それとも別のプログラムから呼び出されているかを判断しているようです。改めてオフィシャルのドキュメントを見てみると、確かにそう書いてあるようにも見えなくもないですね。読みづらいことには変わりないですけどね。

‘__main__’はトップレベルのコードが実行されるスコープの名前です。モジュールが、標準入力から読み込まれたとき、スクリプトとして実行されたとき、あるいはインタラクティブプロンプトのとき、__name__には’__main__’が設定されます。
モジュールは、自身の__name__をチェックすることでメインスコープで実行されているかどうかを確認できます。これはモジュールがスクリプトとして、あるいはインポートでなくpython -mで起動されたときに実行するコードの条件として使用できる一般的なイディオムです。

で、何に使えるの?

これです。結局に何に使うのこれ?ってことですよ。例えば、単体テストと結合テストで振る舞いを変えたいとかそういう時に使ったりするようです。単体テスト時のみ初期値を入れ込んでおきたいときなどに利用されていたり、単体で関数やメソッドを呼び出してチェックができるようにしておいたりとかすることが多いみたいです。

いかがでしたでしょうか、if __name__ == ‘__main__’:理解できましたか?もし気に入ったらシェアなどよろしくおねがいします。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です