Pythonのスクリプトを書いていると、ファイルの末尾によく以下のような記述を見かけることがあります。
if __name__ == "__main__":
main()
これは「おまじない」として定型的に書かれることが多いですが、実際には「そのファイルがスクリプトとして直接実行されたのか」、それとも「他のファイルからモジュールとしてインポートされたのか」を判定するための重要な制御構文です。
この記事では、特殊変数 __name__ の仕組みと、この構文が必要になる理由について解説します。
課題:インポートしただけで実行されてしまう
Pythonの import 文は、指定されたファイルを読み込み、その中のコードを上から順にすべて実行します。
関数やクラスの「定義」だけでなく、関数の「呼び出し(実行)」も書かれている場合、インポートした瞬間にそれらが勝手に実行されてしまいます。
例:問題のあるコード (greeter.py)
def say_hello():
print("Hello from greeter!")
# 関数を定義した後、すぐに呼び出している
print("--- greeter.py の読み込み ---")
say_hello()
このファイルを直接実行する分には問題ありません。しかし、別のファイルから利用しようとすると問題が起きます。
利用側 (app.py)
import greeter
print("--- app.py の処理開始 ---")
実行結果 (python app.py):
--- greeter.py の読み込み ---
Hello from greeter!
--- app.py の処理開始 ---
app.py は単に greeter の機能を使いたかっただけなのに、インポートした時点で greeter.py 内の say_hello() が勝手に実行されてしまいました。
解決策:__name__ 変数による分岐
この問題を解決するのが、Pythonが自動的に設定する特殊変数 __name__ です。この変数には、実行状況に応じて以下の値が入ります。
- 直接実行された場合:
__name__には文字列"__main__"が入る。 - インポートされた場合:
__name__には モジュール名(ファイル名) が入る。
この性質を利用して、「直接実行されたときだけ処理を行う」という分岐を作ります。
修正後のコード (greeter.py)
def say_hello():
print("Hello from greeter!")
# 直接実行された場合のみ、以下のブロックが実行される
if __name__ == "__main__":
print("--- greeter.py の直接実行 ---")
say_hello()
動作の確認
1. 直接実行した場合 (python greeter.py) __name__ は "__main__" となるため、if ブロックの中身が実行されます。
--- greeter.py の直接実行 ---
Hello from greeter!
2. インポートした場合 (python app.py) __name__ は "greeter" となるため、if ブロックは False となり、中身は実行されません。関数定義だけが読み込まれます。
--- app.py の処理開始 ---
これで、意図しない実行を防ぐことができました。
一般的な構成(main()関数の利用)
Pythonプログラムでは、処理の起点となるコードを main() という関数にまとめ、それを if __name__ == "__main__": ブロックから呼び出す構成が推奨されます。
def process_data():
print("データを処理しています...")
def main():
"""メインの処理"""
print("スクリプトを開始します。")
process_data()
print("スクリプトを終了します。")
if __name__ == "__main__":
main()
こうすることで、グローバル変数の乱立を防ぎ、コードの可読性を高めることができます。また、外部からテストコードで main() 関数だけを呼び出すといった柔軟な運用も可能になります。
まとめ
- Pythonファイルは、直接実行時もインポート時も中身が実行されます。
- 特殊変数
__name__は、直接実行時は"__main__"、インポート時はモジュール名になります。 if __name__ == "__main__":を使うことで、スクリプトとして実行された時だけ動くコード(テスト実行やメイン処理)を記述できます。- モジュールとして再利用可能なコードを書くための基本的な作法です。
