【Python】__main__ の仕組みを徹底解説!ハンズオン付き5.8

当サイトではアフィリエイト広告を利用しています。

リファレンス

Python でスクリプトを実行するときに頻繁に出てくる if __name__ == "__main__":
これが何を意味するのか、どう使うのが正しいのか、初心者向けに ハンズオン形式 で解説します!


📝 目次

  1. __main__ とは?
  2. if __name__ == "__main__" の基本
  3. モジュールとして実行した場合とスクリプトとして実行した場合
  4. -m オプションで実行するとどうなる?
  5. __main__ のディレクトリの影響
  6. ハンズオン:実際に動かしてみる

1️⃣ __main__ とは?

Python では、スクリプトの実行方法によって __name__ の値が変わります。

  • スクリプトとして直接実行 すると __name__"__main__" になる。
  • モジュールとしてインポート すると __name__ はモジュール名になる。

試しに、以下のスクリプトを実行してみましょう。

# sample.py
print(__name__)  

実行結果:

$ python sample.py
__main__

スクリプトとして直接実行すると、__name__"__main__" になっていることが分かります。


2️⃣ if __name__ == "__main__" の基本

if __name__ == "__main__": は、 スクリプトとして直接実行されたときだけ実行されるコード を記述するために使います。

🎯

# script.py
def greet():
    print("Hello, Python!")

if __name__ == "__main__":  
    greet()

実行:

$ python script.py
Hello, Python!

しかし、このスクリプトをモジュールとして import すると…?

# main.py
import script  # script.py をインポート

実行結果:

$ python main.py
(何も表示されない)

なぜなら、if __name__ == "__main__": の中のコードは実行されないからです!


3️⃣ モジュールとして実行するとどうなる?

__name__ の値は、 モジュール名 になります。

# module_example.py
print(f"モジュールの名前: {__name__}")

これを別のスクリプトからインポートしてみましょう。

# test.py
import module_example

実行:

$ python test.py
モジュールの名前: module_example

モジュールとしてインポートされると、__name__"__main__" ではなく モジュール名 になることが分かります。


4️⃣ python -m で実行するとどうなる?

通常のスクリプト実行とは異なり、python -m を使うと、 モジュールとして実行 されます。

例えば、以下のようなディレクトリ構成を作成します。

mypackage/
  ├── __init__.py
  └── main_script.py

main_script.py の内容:

# main_script.py
print(f"実行時の __name__: {__name__}")

if __name__ == "__main__":
    print("スクリプトとして実行されました!")

❶ 通常の実行:

$ python mypackage/main_script.py

結果:

実行時の __name__: __main__
スクリプトとして実行されました!

-m を使った実行:

$ python -m mypackage.main_script

結果:

実行時の __name__: mypackage.main_script

if __name__ == "__main__" の中のコードは 実行されない ことが分かります!


5️⃣ __main__ のディレクトリの影響

Python は __main__ を実行するとき、そのスクリプトがある ディレクトリを sys.path の先頭 に追加します。

試しに、以下のスクリプトを実行してみましょう。

# sys_path_check.py
import sys
print(sys.path)

実行:

$ python sys_path_check.py

結果(例):

['/path/to/current/directory', ...]

これは、 カレントディレクトリがモジュール検索の優先順位の最上位にくる ことを意味します。

そのため、標準ライブラリの math モジュールと、同じ名前の math.py がカレントディレクトリにあると…?

mypackage/
  ├── __init__.py
  ├── math.py  # これが標準モジュールと衝突!
  └── main.py

これを防ぐために、
仮想環境を使う
適切な sys.path の管理
を心がけましょう!


6️⃣ ハンズオン:実際に試してみる!

🔥 ハンズオン1:__main__ の確認

  1. test_main.py を作成
  2. __name__ の値を出力
# test_main.py
print(f"このスクリプトの __name__: {__name__}")

実行:

$ python test_main.py

予想される結果:

このスクリプトの __name__: __main__

🔥 ハンズオン2:モジュールとしての実行

  1. module_test.py を作成
# module_test.py
print(f"このモジュールの __name__: {__name__}")
  1. import してみる
# main_test.py
import module_test
print("main_test.pyのコードが実行されました!")

実行:

$ python main_test.py

予想結果:

このモジュールの __name__: module_test
main_test.pyのコードが実行されました!

つまり、 import されたモジュールの __name__"__main__" ではなく、モジュール名になる!


🎯 まとめ

if __name__ == "__main__":スクリプトとして実行されたときだけ動作 する。
import すると __name__ はモジュール名になる。
python -m で実行すると、__name__ はモジュール名のまま。
sys.path による影響で、カレントディレクトリのモジュールが優先されることに注意!


これで __main__ の基本が理解できたはず!🔥
ぜひハンズオンを試して、Python の仕組みを深く理解しましょう! 🚀