いふねーむいこーるいこーる"めいん"

Pythonのプログラムでよく見ることになる以下のコード

if __name__ == "__main__":

呪文のようにとりあえず書いているけど、実際どういう意味があるのか。
忘れないようにメモ書き程度で残す。
※コードはPython3

全体

一般的には以下のように書いてある

def test():
    print("これはテスト")
    
if __name__ == "__main__":
    test():

このtest1.pyを実行すると

>>python test1.py
これはテスト
>>

これは以下のコードと同じ

def test():
    print("これはテスト")
test():

「同じならif __name__ == "__main__":って必要ないやん」
ってなるけど、普通に意味はある。
それはtest1.pyを外部からインポートする場合、test()実行させないため
どういうことか、1つ1つ細かく見ていく

__name__とは

__name__というのは特殊属性1の1つで
どこのプログラムから呼び出されているのかがわかるもの。
ファイル指定で呼び出した場合は、mainが入る

例えば

def print_test():
    print(__name__)

if __name__ == "__main__":
    print("これはメイン")
    print_test()

というプログラムを以下のようにmain.pyでインポートする

import name_test

name_test.print_test()

この状態でそれぞれ実行すると

>>python main
name_test
>>python name_test
これはメイン
__main__

というようになる。
main.pyではインポート先からprint_test()を呼び出しているので、
インポートしているモジュール名name_testがnameに入る。
そのため、name_test.pyのif __name__ == "__main__":はFalseになる。

一方name_test.pyを直接実行した場合、ファイルを指定して呼び出しているので、
nameにはmainが入る。
そのため、name_test.pyのif __name__ == "__main__":はTrueになる。

if __name__ == "__main__":の必要性

もしこのif文がない、以下のようなコードをインポートする。

def print_test():
    print(__name__)

print_test()
import name_test2

print("main.py")

このmain.pyを実行すると

>>python main
name_test2
main.py
>>

実行してもいないのに、name_testが表示される。
これはインポートする際に、name_test2.pyのprint_test()を実行してしまうため。
つまり「if __name__ == "__main__":」は
関数や関数の外で実行されるものを外部参照際に実行させないようにするために使われる!

応用方法

結局「if __name__ == "__main__":」はどうゆう時に使用するかというと
モジュール作った際、テストする時に使用する」というのが一般的。
テストする時はif文にテスト用のプログラムを書いて、そのファイルを直接実行する。
本番では、インポートするプログラムを実行する。

実際に例を出すと入力した数値を2倍にして返すモジュールを作る。
ただモジュールとして利用する前にテストする場合、以下のように書く。

def baipush(int i):
    i *= 2
    return i

if __name__ == "__main__":
    print("これはテスト")
    print(baipush(3))

このプログラムを実行すると

>>python nibai.py
これはテスト
6
>>

これにより、正しく実装されているのが確認できたので、
あとはインポートするメインのプログラムで実行すればいい。
このテストはif文の中に書いてあるので、前述で話した通り、
メインのプログラムで実行した場合は、実行されない。

まとめ

  • 記述例は以下の通り
def test():
    print("これはテスト")
    
if __name__ == "__main__":
    test():
  • nameはどこのプログラムから呼び出されているか知るための特殊属性
  • 「if __name__ == "__main__":」は外部参照時に関数の実行を避けるために使用される
  • 応用方法は主にモジュールのテストするため

  1. xxxという記法で書かれた変数。有名なものだと_init_