コンテンツにスキップ

Top

Python で よく見る if name=="main": って何?

Python を始めるとまず最初に見るのが以下のようなコードですね。

def func():
    print('hoge')

if __name__=="__main__":
   func()

この if __name__=="__main__": って何でしょうか?

これは見慣れないだけでただのif文です。

__name____main__ だった時だけ、以下を実行する、ということです。

いや、__name__なんてわしゃしらんがな、と思うかもしれないですが、これはPython側が自動で設定する値で、pythonから呼び出されたスクリプトファイルの場合だけ、__main__という値が埋め込まれます。

例えば、以下のようなhoge.pyを作ったとして、
hoge.py

print (__name__)

def func():
    print('hoge')

if __name__=="__main__":
   func()

実行すると、

PS> python hoge.py
__main__
hoge
となります。
勝手に __name__ という変数を用意してくれて勝手に__main__と入れてくれている、ということです。

ほーん、で?となりますよね。
だって、そんなif文使わないで、

def func():
    print('hoge')

func()

でいいじゃん、ってなもんです。
実際、結果は同じですしね。

で、この変なおまじないがなんの役に立つかというと、ファイル分割したとき なんです。

では、今のとほとんど同じコードをmain.pyとsub.pyの2つのファイルに分けて、main.pyからsub.pyのfunc()を呼び出して使うことにしてみましょう。

main.py

import sub

sub.func()

sub.py

def func():
    print('hoge')

では実行してみましょう。

PS> python main.py
hoge

うまくいきました。
ではこの時のそれぞれの __name__ をprint文を入れて見てみましょう。

main.py

import sub

print('main:' + __name__)

sub.func()

sub.py

def func():
    print('sub:' + __name__)

では実行してみましょう。

PS> python main.py
main:__main__
sub:sub

sub.py の __name__ が sub になってますね。

これはモジュール名がそのまま表示されます。

pythonはファイル名がそのままモジュール名になるので、sub.pyだとsubというわけです。
もしsub.pyのファイル名をhoge.pyに変えたらhogeにしなといけません。

で、なのですが、これにより何のメリットがあるかというと、sub.pyで単体動作確認したい場合です。

以下のようなsub.pyを作成したとしましょう。

sub.py

def func():
    print('sub:' + __name__)

func()

これにより、sub.pyを実行すると、

PS> python .\sub.py
sub:__main__
とfunc()関数の動作確認ができました。

でもこの状態で、main.pyを実行すると

PS> python .\main3.py
sub:sub
main:__main__
sub:sub
あれれ?sub:subが2行ありますね?
そう。sub.pyの単体テスト用のコードが余計なことをしている、ということです。

でも、もし、sub.pyを以下のように変更してみると、

def func():
    print('sub:' + __name__)

if __name__=="__main__":
    func()

sub.pyの実行はちゃんとfunc()が呼び出されますが、

python .\sub.py
sub:__main__

main.pyの時は、

PS? python .\sub.py
main:__main__
sub:sub

と、main.pyの中での呼び出しのみ、(sub:subが2行出ない)のでばっちり期待通りです!

python で直接たたかれたxxx.pyの__name____main__になることに目をつけた回避法、ということです。

んで、結局、なんでmain.pyに if name=="main": つけるの?というと、、、

意味はないです!

そう。やっぱりいらないんですね(笑)
なんとなく、慣習的な感じで残っているだけだと思います。

以上。