__main__
--- トップレベルのスクリプト環境¶
Python では、 __main__
という特別な名前が次の二つの重要な用途で使われます:
プログラムのトップレベル環境の名前。
__name__ == '__main__'
という式でチェックすることができる。Python パッケージにおける
__main__.py
ファイル。
どちらも Python のモジュールに関わる機能です。 1つ目はユーザーがどうモジュールを使うか、2つ目はモジュールとモジュールがどうやりとりするかに関係します。 詳細は以下で説明します。 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 モジュール:
$ python3 helloworld.py Hello, world!
Python インタープリタにPython
-m
オプションとして渡される Python モジュールまたはパッケージ:$ python3 -m tarfile usage: tarfile.py [-h] [-v] (...)
標準入力から Python インタープリタが読み込む Python コード:
$ echo "import this" | python3 The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. ...
Python インタープリタに
-c
オプションで渡される Python コード:$ python3 -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__'
というコードは、このようなときに役立ちます。
このブロックの中にあるコードは、当該のモジュールがトップレベル環境で実行されていない限り、実行されません。
Putting as few statements as possible in the block below if __name___ ==
'__main__'
can improve code clarity and correctness. Most often, a function
named main
encapsulates the program's primary behavior:
# 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. python3 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:
$ python3 -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[2] 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 contents of __main__.py
typically isn't fenced with
if __name__ == '__main__'
blocks. Instead, those files are kept short,
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, minimal __main__.py
like the venv
one mentioned below are 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`!')
if '__file__' in dir(__main__):
print(__main__.my_name, "found in file", __main__.__file__)
else:
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:
$ python3 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:
$ python3 start.py
Dinsdale found in file /path/to/start.py
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
Note that in this case the __main__
scope doesn't contain a __file__
attribute as it's interactive.
The __main__
scope is used in the implementation of pdb
and
rlcompleter
.