【知らないとやばい!?】Pythonの「if __name__ == '__main__':」の使い方

# はじめに
こんにちは！タランチュラです。
突然ですが、Pythonでスクリプトを書いていると頻繁に目にする```if __name__ == '__main__':```という構文、ご存じでしょうか？
この記事では、このおなじみの構文がいったい何を意味し、なぜ使われるのかをサクッと解説していきます。

プログラミング経験が浅い方や、Pythonを使い始めたばかりで「とにかく動くから何となく使っている」という方を主な対象読者としています。逆に、Python歴の長い方にとっては復習・再確認の内容になるかもしれません。

僕はXで統計やデータサイエンスに関する情報発信を行う傍ら、データ系職種専門の求人広告サイト「DSの森」を運営しています。興味があればぜひチェックしてみてください。

https://x.com/tarantula_ds_/

https://x.com/tarantula_ds_/status/1903975049939284465/

本記事が少しでもお役に立ちましたら、「いいね」や「ストック」をしていただけると励みになります。最後までお付き合いいただけると嬉しいです。


# Pythonにおける```__name__```とは
Pythonでは、モジュール・関数・クラスなど“プログラム要素”として定義されたオブジェクトが持つ特別な属性の一つに、__name__があります。ただし、文字列や数値のような一般的なオブジェクトはこの属性を持たないため、「すべてのオブジェクトが持っているわけではない」という点に注意が必要です。

例えば、以下のような関数とクラスを定義します。
```python
def func():
    print(func.__name__)  # "func"

class MyClass:
    pass

print(MyClass.__name__)   # "MyClass"
```
これを実行すると、それぞれ定義名がそのまま表示されます。

一方、モジュールの場合は、やや挙動が異なります。
モジュールが直接実行されるか、あるいは別のファイルからimportされるかで、```__name__```の値が変わる点が特徴的です。
具体的には、ターミナルから直接実行した際には`"__main__"`、インポートされた場合にはモジュール名が入ります。

たとえば、以下のコードを```my_module.py```として用意します。
```python
# my_module.py

print("Module name:", __name__)

def func():
    print("Function name:", func.__name__)

class MyClass:
    pass

func()
print("Class name:", MyClass.__name__)
```
ターミナルなどのスクリプトで直接```python my_module.py```を実行すると、出力はだいたい以下のようになります。
```python
Module name: __main__
Function name: func
Class name: MyClass
```

一方、別のファイルで```import my_module.py```を呼び出してみると、
```python
Module name: my_module
Function name: func
Class name: MyClass
```
のように出力されます。

このように、モジュールの__name__だけは「直接実行時」と「import時」で異なる値を取るわけです。ここで活用されるのが、次に解説する```if __name__ == '__main__':```構文です。

「モジュールとして実行されているのか、それともスクリプトとして直接呼ばれているのか」を判定し、処理を切り分けるために利用されます。


# ```if __name__ == '__main__':```が果たす役割
Pythonファイルをモジュールとしてインポートせずに、直接スクリプトとして実行した場合には、ファイルの先頭から順番にコードがすべて読み込まれて実行されます。

しかし、他のファイルからインポートされる場合には「モジュールが読み込まれる」という処理だけ行われ、いわゆる“メインの処理”を動かしたくないケースがあります。

こうした「**直接実行のときだけ動かしたい処理**」を切り分けるために使用されるのが、```if __name__ == '__main__':```構文です。以下の例を見てください。

```python
# sample.py
def greet():
    print("Hello from greet()!")

def main():
    """メインとなる処理"""
    greet()
    print("This script is executed directly!")

# ここがポイント
if __name__ == '__main__':
    main()
```
スクリプトで直接モジュールを```python sample.py```で実行する場合は、```__name__```には```"__main__"```がセットされているため、```if __name__ == '__main__':```以下の```main()```関数が呼び出され、処理が行われます。
```
Hello from greet()!
This script is executed directly!
```

続いて、以下のように他のファイルからimportするケースを想定します。
```python
# another_script.py
import sample

sample.greet()
```
こちらの実行結果は、
```
Hello from greet()!
```
この場合は、```sample.py```がモジュールとして読み込まれただけなので、```__name__```は```"sample"```になり、```if __name__ == '__main__':```以下の処理は実行されません。

このように、「**スクリプトとして実行したときだけ動かしたい処理**」と「**モジュールとして読み込まれたときにはスキップしたい処理**」を分ける役割を果たすのが```if __name__ == '__main__':```構文です。

大規模プロジェクトやライブラリの中にデモやテストを組み込む場合にも、便利に使われる仕組みです。

# メリットと実践的な使い道
## ```if __name__ == '__main__':``` のメリット
```if __name__ == '__main__':```を使うメリットとしては3点ほど挙げられます。
### 1. モジュールの再利用性が高まる
「直接スクリプトとして実行するか」、「他のファイルからimportするか」で処理を分けられます。結果として、同じコードを複数の場所に書く必要がなくなり、再利用が容易になります。

### 2. デモコードやテストコードの切り分けが簡単
ライブラリの使い方サンプルや簡単なテストコードを“**メイン実行時のみ**”走らせることができるため、開発・学習どちらのシーンでも便利に活用できます。

### 3. 無駄な処理の実行を防げる
import時に不必要なデータ読み込みや大掛かりな処理が動かないようにできます。これにより、アプリケーションの起動が軽くなったり、予期せぬ副作用を防ぐことにもつながります。

## 実践的な使い道
続いて、```if __name__ == '__main__':```の実践的な使い道についてまとめます。
### 使った方が良いとき
#### 1. ツールとしても、ライブラリとしても使いたいファイルがある場合
スクリプトを直接実行すればユーティリティとして動き、importすれば他のコードから関数やクラスを再利用できます。

#### 2. 簡易的なテストやデモを内包させたい場合
ファイルの最後にテストコードやデモ用コードを書いておけば、動作確認が手軽にできます。

#### 3. アプリケーションのエントリポイントを明示したい場合
どこが「メインの処理か」を明確にし、読み手（他の開発者や自分自身）へのガイドとして機能し、わかりやすくなります。


### 使う必要がないとき
#### 1. ライブラリやモジュールとしてのみ使われる想定のコード
「実行するためのメイン処理」が存在しない場合は、if __name__ == '__main__':は不要です。常にimportされるだけなら問題ありません。

#### 2. 別途メインスクリプトを用意している場合
すでに呼び出し口となるスクリプトを分けているなら、個々のモジュールにメイン処理を置く必要はありません。

#### 3. プロジェクト全体の設計で「メインコードは一カ所」と定義されている場合
複数のファイルでメインコードを散らばらせるより、1ファイルに集中させる方がわかりやすいケースもあるため、プロジェクトの方針次第では使わないこともあります。

### まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584936/19b72c5c-cafc-44a3-9b1f-02623dcb07d7.png)

# さいごに
最後までお読みいただき、誠にありがとうございます！
```if __name__ == '__main__':```の基本的な仕組みや活用方法について、少しでも理解が深まるきっかけになれば幸いです。
もし本記事がお役に立ちましたら、ぜひ「いいね」や「ストック」をしていただけると励みになります。

また、Xで統計やデータサイエンスに関する情報発信を行っておりますので、フォローいただけると嬉しいです。

https://x.com/tarantula_ds_/

今後とも、どうぞよろしくお願いいたします。