「おまじない」って言われる if __name__ == ('__main__'):
をちゃんと理解したい
おさえたいポイント
そもそも、__name__
と __main__
ってなに?
__name__
とは:
クラス、関数、メソッド、デスクリプタ、ジェネレータインスタンスの名前が入るための特殊な変数
モジュールやパッケージがインポートされると、__name__にはモジュールの名前がセットされる
■インタプリタで実行
標準モジュール.py
>>> import subprocess
>>> subprocess.__name__
'subprocess'
実行フローと結果
- import文でモジュールを読み込む
- module(ここではsubprocess).__name__で特殊属性の__name__を表示する
- 'subprocess'としてモジュール名が表示される
■ファイルで実行
directory/
| -- my_function.py
| -- test.py
my_function.py
def show_name():
print(__name__)
test.py
import my_function
my_function.show_name()
$ python test.py
my_function
my_function
実行フローと結果
- my_function.py : show_name()という関数を定義し、__name__をprint文で表示する
- test.py : my_function.pyをモジュールとしてimport文で読み込みshow_name()を実行する
- ターミナルで test.py を実行する
- ファイルがモジュールとして読み込まれると、拡張子 .py を除くファイル名がモジュール名としてセットされる。
注意点
- my_fanction x 2 の状態で結果が返ってきている。
あっ、そういうことか❗️
"基本的な動作として、モジュールは何かしらの方法で制御しないと、importした時点で関数が実行されてしまう。だから、この「おまじない(if __name__ == '__main__':
)」の文が必要ってこと。
__main__
とは:
トップレベルコードが実行される環境の名前です。"トップレベルコード "とは、最初に実行を開始するユーザー指定のPythonコードのことです。そのコードは必要とする他のすべてのモジュールをインポートするので「トップレベル」と定義されている。 "トップレベルコード "はアプリケーションへのエントリポイントとも呼ばれる。
※要はターミナルで直接スクリプトを実行したのがこの状態。
■ おまじない"有り無し"スクリプトを実行してみる
my_function.py
def show_name():
print(__name__)
# おまじない有り
if __name__ == ('__main__'):
show_name()
$ python my_function.py
$ __main__
my_function.py
def show_name():
print(__name__)
# おまじない無し
$ python my_function.py
$
実行フロートと結果
- おまじない有り : 一番の上位のモジュールとしてmy_function.pyが実行されているので、トップレベルの環境名__main__が変数__name__に代入され、if文でTrueと判別される。 次にshow_name()メソッドが実行され、print文で変数__name__つまり、__main__が返ってきている。
- おまじない無し : show_name()メソッドが呼び出されていないので、当然なにも表示されない。
本題に戻って、結局 if __name__ != ( '__main__' )
にしたらどうなるのか?
my_function.py
def show_name():
print(__name__)
if __name__ != ('__main__'):
show_name()
■ファイルを直接実行
$ python my_function.py
$
■モジュールとして読み込んで実行
$ python test.py
my_function
my_function
実行フロートと結果
- スクリプトファイルを直接実行した場合、左辺も右辺も値は同じ__main__で同じなので、!=の判定結果でFalseとなりshow_name()は実行されず、結果はなにも表示されない。
- モジュールとして読み込んだ場合は、逆に読み込まれた時点で1回実行され、次にshow_name()でもう一度実行され、結果my_functionが2つ表示されることになる。
結論
- このおまじないは、"スクリプトの実行を制御する文" ということですね❗️