if __name__ == "__main__": ナニコレ?
なんでこんな書き方するの?どうやって main 関数が実現されてるの?
Pythonには独自の概念が多く、初心者には「おまじない」と説明を済まされる謎コードがいくつも存在します。
その代表例が、Pythonを書いているとよく見かけるこの一文です。
if __name__ == "__main__":
main()
「……何コレ?」
正直な話、「なんかおまじないみたいなやつ」「main関数を実行するための決まり文句」くらいの理解で使ってませんか?
しかし、ちゃんと仕組みを知ると「なるほど、だからこの書き方なのか」となります。
この記事では、
-
__name__ってそもそも何? -
__main__ってどこから来た? - なんでこんな回りくどい書き方をするの?
- これを書くと Python はどう動くの?
を、できるだけわかりやすく説明していきます
そもそも __name__ って何?
結論から言うと、name は 「このファイルがどうやって実行されたか」 を表す変数です。
Pythonファイルは実行されるとき、自動でいくつかの変数を持ちます。
その中のひとつが __name__。
ファイルを直接実行したとき
例えば、こんな sample.py があるとします。
# sample.py
print(__name__)
これをそのまま実行すると、
python sample.py
出力はこうなります。
__main__
つまり、直接実行されたファイルの __name__ は "__main__" になるというルールがあります。
他のファイルから import されたとき
今度はこんな構成にします。main.pyとsample.pyの二つのファイルを用意します。
main.py
sample.py
ファイルの中身はそれぞれ以下の通りにします
# sample.py
print(__name__)
# main.py
import sample
これを実行すると、
python main.py
出力は
sample
になります。
ここがポイントで、
-
直接実行されたとき →
__name__ == "__main__" -
import されたとき →
__name__ == ファイル名
という挙動をします。
if __name__ == "__main__": は何をしている?
ここまで来ると、この条件文の意味が見えてきます。
if __name__ == "__main__":
main()
これはつまり、「このファイルが直接実行されたときだけ main() を動かす」という意味です。
逆に言うと、
- import されたときは
main()を実行しない - 直接実行されたときだけ処理を走らせる
という制御をしています。
なんでこんな書き方をするの?
ここが一番大事なところです
悪い例
def main():
print("処理開始")
main()
これでも動きます。でも問題があります。
このファイルを import した瞬間 に main() が実行されてしまいます。
import sample # ← ここで main() が勝手に動く
ライブラリとして使いたいとき、「読み込んだだけなのに処理が走る」のはかなり困ります。
if __name__ == "__main__": を使うとどうなる?
def main():
print("処理開始")
if __name__ == "__main__":
main()
これなら、
- 直接実行 →
main()が動く - import → 関数定義だけされて、処理は動かない
という、めちゃくちゃ都合のいい挙動になります。
main関数ってPythonに最初からあるの?
実はここ、誤解されがちなんですが…
Pythonには 公式な main 関数は存在しません。CやJavaみたいに「main関数がエントリーポイントです!」という言語仕様はないです。
じゃあなんで main() って書くのかというと、
- プログラムの入口が分かりやすい
- 他の言語経験者にも読みやすい
- 処理をまとめやすい
という慣習です。
Pythonはどうやって「main」を実現してるの?
実際の流れをざっくり書くとこんな感じ。
- Pythonがファイルを読み込む
- 上から順にコードを実行
-
__name__に値をセット- 直接実行 →
"__main__" - import → モジュール名
- 直接実行 →
-
if __name__ == "__main__":を判定 - Trueなら
main()を呼ぶ
つまり、「Pythonが main を特別扱いしているわけではない」というのがポイントです。
ただの if 文と関数呼び出しです。
まとめ
最後に雑まとめ。
-
__name__は「実行された状況」を表す変数 - 直接実行されたファイルは
__name__ == "__main__" - import されたファイルは
__name__ == モジュール名 -
if __name__ == "__main__":は 直接実行されたときだけ処理を動かすための仕組み - main関数はPythonの仕様ではなく慣習
