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__
でもこの状態で、main.pyを実行すると
PS> python .\main3.py
sub:sub
main:__main__
sub:sub
そう。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": つけるの?というと、、、
意味はないです!
そう。やっぱりいらないんですね(笑)
なんとなく、慣習的な感じで残っているだけだと思います。
以上。