原文: Python if __name__ == __main__ Explained with Code Examples
Python インタープリターは、Python ファイルを読み込むとまずいくつか特別な変数を設定します。それからファイルに書かれたコードを実行します。
その変数の 1 つが __name__
です。
順を追ってこの記事とコードスニペットを読んでいけば、if __name__ == "__main__"
の使い方とその重要性がわかるようになるでしょう。
Python モジュールの解説
Python ファイルは拡張子 .py
が付くファイルで、モジュールとも呼ばれます。モジュールは、関数、クラス、そして変数を定義できます。
インタープリターがモジュールを実行する際、実行されるモジュールがメインプログラムの場合は、__name__
変数が __main__
に設定されます。
しかしそのモジュールを他のモジュールからインポートしているコードの場合は、__name__
変数はそのモジュールの名前に設定されます。
例を見てみましょう。file_one.py
という名前の Python モジュールを作成し、その中にこのトップレベルコードを貼り付けてください。
このファイルを実行すると、先ほど述べた内容が確認できます。このモジュールの変数 __name__
は __main__
に設定されます。
file_one の __name__ の設定内容: __main__
(訳注: 実行時に SyntaxError: Non-ASCII character '\xe3' in file file_one.py on line 1, but no encoding declared
というエラーが発生する場合は、Python 3.x 系で実行するか、ファイルの先頭に # -*- coding: utf-8 -*-
という行を追加してください。)
ではもう 1 つ file_two.py
という名前のファイルを追加して、中にこのコードを貼り付けてください。
そして file_two
モジュールをインポートするために、file_one.py
のコードを次のように変更してください。
もう一度 file_one
のコードを実行すると、file_one
の __name__
変数は変わらず __main__
のままですが、file_two
の __name__
変数はモジュール名、つまり file_two
に設定されます。
実行結果は次のようになります。
file_two の __name__ の設定内容: file_two
file_one の __name__ の設定内容: __main__
しかし直接 file_two
を実行した場合には、__name__
が __main__
に設定されるのが確認できます。
file_two の __name__ の設定内容: __main__
実行するファイル / モジュールの __name__
変数は常に __main__
となります。ですがその他のインポートされたモジュールの __name__
変数は、モジュール名に設定されます。
Python ファイルの命名規則
__name__
と __main__
は通常このような形で使われます。
if __name__ == "__main__":
# ここに処理内容を記述
これがどのように機能するか、そしてこれらの変数をどうやって使うかを見ていきましょう。
file_one
と file_two
を次のように変更してください。
file_one
:
file_two
:
先ほどと同様に file_one
を実行すると、プログラムが 2 つのモジュールのどちらが __main__
かを認識して、if else
文に従ってコードを実行したことが確認できます。
実行結果は次のようになります。
file_two の __name__ の設定内容: file_two
file_two がインポートされて実行されました
file_one の __name__ の設定内容: __main__
file_one が直接実行されました
今度は file_two
を実行してみると、__name__
変数が __main__
に設定されることが確認できます。
file_two の __name__ の設定内容: __main__
file_two が直接実行されました
このようなモジュールがインポートまたは実行されると、関数がインポートされ、トップレベルコードが実行されます。
その処理の動作を確認するために、ファイルを次のように変更しましょう。
file_one
:
file_two
:
これで関数が読み込まれますが、実行はされません。
関数を実行するには、file_one
の if __name__ == "__main__"
の部分を次のように変更してください。
if __name__ == "__main__":
print("file_one が直接実行されました")
function_two()
else:
print("file_one がインポートされて実行されました")
file_one
を実行すると次のように表示されるはずです。
file_two の __name__ の設定内容: file_two
file_two がインポートされて実行されました
file_one の __name__ の設定内容: __main__
file_one が直接実行されました
function_two が実行されました
また、インポートしたファイルの関数を実行することもできます。file_one
の if __name__ == "__main__"
の部分を次のように変更しましょう。
if __name__ == "__main__":
print("file_one が直接実行されました")
function_two()
file_two.function_three()
else:
print("file_one がインポートされて実行されました")
実行結果は次のようになるでしょう。
file_two の __name__ の設定内容: file_two
file_two がインポートされて実行されました
file_one の __name__ の設定内容: __main__
file_one が直接実行されました
function_two が実行されました
function_three が実行されました
ここで、例えば file_two
モジュールが大きくなってたくさんの関数があり (この例では 2 つですが)、その全部はインポートしたくない場合を考えます。file_two
を次のように変更してください。
モジュールから特定の関数をインポートするには、file_one
ファイルで from
import ブロックを使います。
まとめ
ファイルをメインプログラムとして実行できるようにしたい場合でも、他のモジュールにインポートされるようにしたい場合でも、__name__
変数が便利に使える場面があります。if __name__ == "__main__"
ブロックを使って、モジュールがインポートされた場合にコードの一部を実行可能にしたり、あるいは不可にしたりできます。
Python インタープリターがファイルを読み込むと、実行中モジュールの場合には __name__
変数は __main__
に、インポートされた場合にはモジュール名に設定されます。ファイルを読み込むとすべてのトップレベルコードが実行されますが、関数やクラスは実行されません。(インポートされるだけです。)
Bra gjort! (スウェーデン語で「よくできました」という意味です!)
筆者の freeCodeCamp プロフィールや Medium プロフィールからこのような記事をもっと読むことができます。その他の作品は GitHub ページをチェックしてください。