# `__main__` --- トップレベルのコード環境

Python では、 `__main__` という特別な名前が次の二つの重要な用途で使われます:

1. プログラムのトップレベル環境の名前。 `__name__ == '__main__'` という式でチェックすることができる。

2. Python パッケージにおける `__main__.py` ファイル。

どちらも Python のモジュールに関わる機能です。 １つ目はユーザーがどうモジュールを使うか、２つ目はモジュールとモジュールがどうやりとりするかに関係します。 詳細は以下で説明します。 Python モジュールがどういうものかについては、 モジュール を参照してください。

## `__name__ == '__main__'`

Python モジュールやパッケージがインポートされるとき、 `__name__` の値はそのモジュールの名前となります。 通常、インポートされる Python ファイル自体のファイル名から拡張子 `.py` を除いたものとなります:

    >>> import configparser
    >>> configparser.__name__
    'configparser'

インポートされるファイルがパッケージの一部である場合は、 `__name__` にはそのパッケージのパスも含まれます:

    >>> from concurrent.futures import process
    >>> process.__name__
    'concurrent.futures.process'

しかし、モジュールがトップレベルのスクリプト環境で実行される場合は、 `__name__` が `'__main__'` という文字列になります。

### 「トップレベルのスクリプト環境」とは

`__main__` は、トップレベルのコードが実行される環境の名前です。 "トップレベルのコード" は、実行を開始する最初のユーザー指定の Python モジュールです。これは、このモジュールがプログラムに必要なすべての他のモジュールをインポートするために、 "トップレベル" なのです。時折、 "トップレベルのコード" は、アプリケーションには エントリーポイント と呼ばれます。

以下のものがトップレベルのスクリプト環境となります:

- インタラクティブプロンプトのスコープ:

      >>> __name__
      '__main__'

- Python インタープリタにファイル引数として渡される Python モジュール:

      $ python helloworld.py
      Hello, world!

- Python インタープリタにPython `-m` オプションとして渡される Python モジュールまたはパッケージ:

      $ python -m tarfile
      usage: tarfile.py [-h] [-v] (...)

- 標準入力から Python インタープリタが読み込む Python コード:

      $ echo "import this" | python
      The Zen of Python, by Tim Peters

      Beautiful is better than ugly.
      Explicit is better than implicit.
      ...

- Python インタープリタに `-c` オプションで渡される Python コード:

      $ python -c "import this"
      The Zen of Python, by Tim Peters

      Beautiful is better than ugly.
      Explicit is better than implicit.
      ...

上記それぞれの場合で、トップレベルのモジュールの `__name__` の値が `'__main__'` となります。

これにより、 `__name__` をチェックすれば各モジュールは自分がトップレベル環境で実行されているかどうかを知ることができます。 このことから、モジュールが import 文で初期化された場合以外の場合でのみコードを実行するため、次のコードがしばしば用いられます:

    if __name__ == '__main__':
        # Execute when the module is not initialized from an import statement.
        ...

参考

あらゆる場合に `__name__` の値がどうセットされるのかについて、詳しくはチュートリアルの モジュール セクションを参照してください。

### 通常の使われ方

一部のモジュールでは、コマンドライン引数をパースしたり標準入力からデータを取得したなど、スクリプト用途のみのコードが含まれています。 このようなモジュールが、例えばユニットテストのため、別のモジュールからインポートされると、そのスクリプト用コードが意図に反して実行されてしまいます。

`if __name__ == '__main__'` というコードは、このようなときに役立ちます。 このブロックの中にあるコードは、当該のモジュールがトップレベル環境で実行されていない限り、実行されません。

`if __name__ == '__main__'` の下のブロックにあるコードはできるだけ少なくした方が、コードの分かりやすさや正確さにつながります。 最もよくあるのが、プログラムの主要な処理を `main` 関数の中にカプセル化することです:

    # echo.py

    import shlex
    import sys

    def echo(phrase: str) -> None:
       """A dummy wrapper around print."""
       # for demonstration purposes, you can imagine that there is some
       # valuable and reusable logic inside this function
       print(phrase)

    def main() -> int:
        """Echo the input arguments to standard output"""
        phrase = shlex.join(sys.argv)
        echo(phrase)
        return 0

    if __name__ == '__main__':
        sys.exit(main())  # next section explains the use of sys.exit

注意すべき点として、もし `main` 関数内のコードをカプセル化せず `if __name__ == '__main__'` の下に直接書いた場合、 `phrase` 変数はモジュール全体からグローバルにアクセスできてしまいます。 モジュール内の他の関数が意図せずローカル変数ではなくそのグローバル変数を使用してしまう可能性があるため、ミスにつながります。 `main` 関数を用意することでこの問題は解決できます。

`main` 関数を使うことのもう一つのメリットとして、 `echo` 関数が分離し、別の場所からインポートできるようになることです。 `echo.py` がインポートされるとき、 `echo` 関数と `main` 関数が定義されますが、 `__name__ != '__main__'` であるため、どちらの関数も呼び出されません。

### パッケージングで考慮すべき点

`main` functions are often used to create command-line tools by specifying them as entry points for console scripts. When this is done, pip inserts the function call into a template script, where the return value of `main` is passed into `sys.exit()`. For example:

    sys.exit(main())

Since the call to `main` is wrapped in `sys.exit()`, the expectation is that your function will return some value acceptable as an input to `sys.exit()`; typically, an integer or `None` (which is implicitly returned if your function does not have a return statement).

By proactively following this convention ourselves, our module will have the same behavior when run directly (i.e. `python echo.py`) as it will have if we later package it as a console script entry-point in a pip-installable package.

In particular, be careful about returning strings from your `main` function. `sys.exit()` will interpret a string argument as a failure message, so your program will have an exit code of `1`, indicating failure, and the string will be written to `sys.stderr`. The `echo.py` example from earlier exemplifies using the `sys.exit(main())` convention.

参考

Python Packaging User Guide contains a collection of tutorials and references on how to distribute and install Python packages with modern tools.

## `__main__.py` in Python Packages

If you are not familiar with Python packages, see section パッケージ of the tutorial. Most commonly, the `__main__.py` file is used to provide a command-line interface for a package. Consider the following hypothetical package, "bandclass":

    bandclass
      ├── __init__.py
      ├── __main__.py
      └── student.py

`__main__.py` will be executed when the package itself is invoked directly from the command line using the `-m` flag. For example:

    $ python -m bandclass

This command will cause `__main__.py` to run. How you utilize this mechanism will depend on the nature of the package you are writing, but in this hypothetical case, it might make sense to allow the teacher to search for students:

    # bandclass/__main__.py

    import sys
    from .student import search_students

    student_name = sys.argv[1] if len(sys.argv) >= 2 else ''
    print(f'Found student: {search_students(student_name)}')

Note that `from .student import search_students` is an example of a relative import. This import style can be used when referencing modules within a package. For more details, see パッケージ内参照 in the モジュール section of the tutorial.

### 通常の使われ方

The content of `__main__.py` typically isn't fenced with an `if __name__ == '__main__'` block. Instead, those files are kept short and import functions to execute from other modules. Those other modules can then be easily unit-tested and are properly reusable.

If used, an `if __name__ == '__main__'` block will still work as expected for a `__main__.py` file within a package, because its `__name__` attribute will include the package's path if imported:

    >>> import asyncio.__main__
    >>> asyncio.__main__.__name__
    'asyncio.__main__'

This won't work for `__main__.py` files in the root directory of a `.zip` file though. Hence, for consistency, a minimal `__main__.py` without a `__name__` check is preferred.

参考

See `venv` for an example of a package with a minimal `__main__.py` in the standard library. It doesn't contain a `if __name__ == '__main__'` block. You can invoke it with `python -m venv [directory]`.

See `runpy` for more details on the `-m` flag to the interpreter executable.

See `zipapp` for how to run applications packaged as .zip files. In this case Python looks for a `__main__.py` file in the root directory of the archive.

## `import __main__`

Regardless of which module a Python program was started with, other modules running within that same program can import the top-level environment's scope (namespace) by importing the `__main__` module. This doesn't import a `__main__.py` file but rather whichever module that received the special name `'__main__'`.

Here is an example module that consumes the `__main__` namespace:

    # namely.py

    import __main__

    def did_user_define_their_name():
        return 'my_name' in dir(__main__)

    def print_user_name():
        if not did_user_define_their_name():
            raise ValueError('Define the variable `my_name`!')

        print(__main__.my_name)

Example usage of this module could be as follows:

    # start.py

    import sys

    from namely import print_user_name

    # my_name = "Dinsdale"

    def main():
        try:
            print_user_name()
        except ValueError as ve:
            return str(ve)

    if __name__ == "__main__":
        sys.exit(main())

Now, if we started our program, the result would look like this:

    $ python start.py
    Define the variable `my_name`!

The exit code of the program would be 1, indicating an error. Uncommenting the line with `my_name = "Dinsdale"` fixes the program and now it exits with status code 0, indicating success:

    $ python start.py
    Dinsdale

Note that importing `__main__` doesn't cause any issues with unintentionally running top-level code meant for script use which is put in the `if __name__ == "__main__"` block of the `start` module. Why does this work?

Python inserts an empty `__main__` module in `sys.modules` at interpreter startup, and populates it by running top-level code. In our example this is the `start` module which runs line by line and imports `namely`. In turn, `namely` imports `__main__` (which is really `start`). That's an import cycle! Fortunately, since the partially populated `__main__` module is present in `sys.modules`, Python passes that to `namely`. See Special considerations for __main__ in the import system's reference for details on how this works.

The Python REPL is another example of a "top-level environment", so anything defined in the REPL becomes part of the `__main__` scope:

    >>> import namely
    >>> namely.did_user_define_their_name()
    False
    >>> namely.print_user_name()
    Traceback (most recent call last):
    ...
    ValueError: Define the variable `my_name`!
    >>> my_name = 'Jabberwocky'
    >>> namely.did_user_define_their_name()
    True
    >>> namely.print_user_name()
    Jabberwocky

The `__main__` scope is used in the implementation of `pdb` and `rlcompleter`.