LoginSignup
1
2

【Python】「if __name__ == '__main__':」ブロックの意味とは?スクリプト実行とモジュール読み込み

Last updated at Posted at 2023-12-07

概要

Pythonのコードでif __name__ == '__main__':というIF文をたまに見かけますよね。Djangoならmanage.pyで見ます。

これってどういう挙動なんだ?って思ったのでサンプルコードで作って確認してみました。

サンプルコード

module_example.py
def say_hello():
    print("もちろんこれも直接実行の時だよ!")

print("これはいつでも表示されるぞ!")

if __name__ == '__main__':
    print("これは直接実行される時だけ表示されるよ!")
    say_hello()

def sample_function():
    print(__name__)    
sample_function()

スクリプト実行とモジュールとしての読み込みとは?

上記のスクリプトを実行すると以下が出力されます。

python3 module_example.py

これはいつでも表示されるぞ!
これは直接実行される時だけ表示されるよ!
もちろんこれも直接実行の時だよ!
__main__

では、別のスクリプトからモジュールとしてインポートした場合はどうなるのでしょうか?

another_script.py

import module_example

上記の実行結果は以下になります。

python3 another_script.py

これはいつでも表示されるぞ!
module_example

まず、上3つの日本語のテキストが一つだけになりました。

「これは直接実行される時だけ表示されるよ!」

「もちろんこれも直接実行の時だよ!」
が出力されていないことがわかります。

つまり、if __name__ == '__main__':ブロックを使用することで、そのスクリプトが直接実行された時のみに実行してほしいことの制御を行うことができるのです。
出力されなくなった2つのテキストはどちらも、if __name__ == '__main__':Trueだった場合に実行されるものです。しかし、よそからスクリプトを読み込まれた場合(モジュールとして読み込まれた場合)はこれが実行されない、ということです。

ではこのIF文のTrueとかFalseになる意味をもう少し考えてみます。
ここで、一番下に出力されていた__main__とかmodule_exampleが関係してきます。

上述のif __name__ == '__main__':というIF文とその結果をみて察しがつくと思いますが、モジュールとして読み込まれた場合はモジュール名が格納され、直接スクリプトとして実行された場合は「__main__」になるのです。

つまり、結論以下のようになります。

・スクリプト実行された場合は、__name____main__である。
 であるので、if __name__ == '__main__':Trueになり、そのブロックが実行される。

・モジュールとしてインポートされて実行された場合は、__name__モジュール名である。
 であるので、if __name__ == '__main__':Falseになり、そのブロックが実行されない。

ちなみに、スクリプトが直接実行されるような状態のことを 「トップレベルのスクリプト環境」("Top-level code")というらしいです。
main --- トップレベルのスクリプト環境 — ...

main is the name of the environment where top-level code is run. "Top-level code" is the first user-specified Python module that starts running. It's "top-level" because it imports all other modules that the program needs. Sometimes "top-level code" is called an entry point to the application.

参考1: djangoのmanage.py

冒頭でも紹介した通り、djangoのmanage.pyでは、if __name__ == '__main__':ブロックを見ることができます。

manage.py
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    """Run administrative tasks."""
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == '__main__':
    main()

ちなみにdef main()は特に何か特別な意味があるわけではなく、プログラミング慣習としてメインプログラムの初めに使うことがある、というイメージです。こういうのをエントリポイント(プログラムの処理の開始地点)と呼ぶらしいです。「どこがこのプログラムのはじめなんだ!?」ということがわかるように、可読性を高める役割があるんですね。

main()でなくてもなんでも良いですが、他のプログラミング言語で使うことが多い?らしいからPythonでもそうしているっぽい。

参考2: __main.py__とは?

似たような概念に__main.py__というファイルがあります。
こちらは以下の記事で紹介していますので、よかったらどうぞ。
【Python】「main.py」とは何か?このファイルから他のモジュールを実行する方法

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2