このページでは、Python スクリプトでよく見る if __name__ == '__main__'
の意味について解説していきます。
書籍やネット上で公開されている Python スクリプトでは下記のように if __name__ == '__main__'
が利用されていることが多いです。
def main():
# 略
if __name__ == '__main__':
main()
これを真似て、上記のように if __name__ == '__main__'
を利用してスクリプトを記述している方も多いのではないのでしょうか?
でも、単に真似て記述しているだけで、if __name__ == '__main__'
の意味合いを理解していない方も多いのではないかと思います。
このページでは、if __name__ == '__main__'
の意味や if __name__ == '__main__'
を利用するメリットについて解説をしていきたいと思います。
Contents
__name__
とは
まず、単純に考えると、if __name__ == '__main__'
は __name__
の参照する文字列が '__main__'
であるかどうかを判断する if
文になります。
この '__main__'
は単なる文字列です。
では __name__
とは何なのでしょうか?この点を深掘りしていきたいと思います。
__name__
を出力してみる
この __name__
の意味合いを理解するために、ここで2つのスクリプトを用意し、実際に __name__
の出力結果を確認していきたいと思います(2つのスクリプトは同じフォルダ内に用意してください)。
直接スクリプトを実行した時の出力結果
まず1つ目に用意するのが、下記の MyCalc.py
になります。
def add(x, y):
return x + y
def sub(x, y):
return x - y
def mul(x, y):
return x * y
def div(x, y):
return x / y
print(__name__ + ' START!')
print(add(5, 2))
print(sub(5, 2))
print(mul(5, 2))
print(div(5, 2))
スクリプトを見ていただければ分かるように、MyCalc.py
では add
・sub
・mul
・div
の4つの関数を定義しています。
また、ご存知の通り、Python スクリプトではファイルの上側の行の処理から順に実行されていくことになります。ただし、関数やクラスの定義に関しては読み込まれるだけで、実行されるのは関数やクラスの定義以外の行の処理となります。
そして、その実行される行で関数やメソッドの呼び出しが行われる際に、そこで初めて関数やクラス内の処理が実行されることになります。
つまり、MyCalc.py
において最初に実行されるのは下記の行の処理となります。この行では、今回注目している __name__
の出力を行なっています。
print(__name__ + ' START!')
そして、それ以降の行で定義した関数呼び出しが行われることで、関数内の処理が実行されることになります。
具体的には、MyCalc.py
内で定義した add
・sub
・mul
・div
の4つの関数に対して引数 x = 5
と y = 2
を指定して実行し、その結果の出力を行なっています。
では、この MyCalc.py
を python
コマンドで実行してみましょう!
結果は下記のようになるはずです。
% python MyCalc.py __main__ START! 7 3 10 2.5
計算結果も上手く表示されているのですが、それよりも注目していただきたいのが __name__
の出力結果です。
上記からも確認できるように、print(__name__ + ' START!')
の出力結果が __main__ + START!
となっているため、__name__
の出力結果は '__main__'
であることが確認できます。
import
してスクリプトを実行した時の出力結果
2つ目に用意するのが、下記の MyMain.py
になります。
import MyCalc
print(__name__ + ' START!')
print(MyCalc.add(10, 3))
print(MyCalc.sub(10, 3))
print(MyCalc.mul(10, 3))
print(MyCalc.div(10, 3))
MyMain.py
では、1行目で先ほど用意した MyCalc.py
をモジュールとして import
しています。このように、Python においては自身で作成したスクリプトも import
してモジュールとして利用することが可能です。
import
後は、__name__
の出力および MyCalc
で定義された関数の実行結果の出力を行なっています。
では、この MyMain.py
を python
コマンドで実行してみましょう!
結果は下記のようになるはずです。
% python MyMain.py MyCalc START! 7 3 10 2.5 __main__ START! 13 7 30 3.3333333333333335
計算結果は置いておくとして、ポイントになるのが __name__
の出力結果です。
MyMain.py
を実行した場合、__name__
の出力は2回行われることになります。
まず import MyCalc
が実行されることによって、MyCalc.py
で定義されている関数の読み込み&下記の行の実行が行われます。
print(__name__ + ' START!')
print(add(5, 2))
print(sub(5, 2))
print(mul(5, 2))
print(div(5, 2))
import
時には関数やクラスの定義の読み込みが行われ、これにより、import
したモジュールの関数やクラスを利用することができるようになります。
ただし、関数やクラスの定義以外の処理に関しては実行されてしまいます。実はここが if __name__ == '__main__'
を利用するメリットにつながってきます(詳細は後述で解説します)。
具体的には、import MyCalc
を実行すれば、関数定義以外の上記の5行が実行されることになります。
そして、上記の1行目での print
の実行結果が、先ほどの MyMain.py
実行結果の下記部分となります。
MyCalc START!
つまり、MyCalc.py
からの __name__
の出力結果は 'MyCalc'
となっています。
直接スクリプトを実行した時の出力結果 で MyCalc.py
を実行した時とは結果が違いますね…。直接スクリプトを実行した時の出力結果 で実行した際には __name__
の出力結果は '__main__'
となっていたはずです。
なぜ、今回と 直接スクリプトを実行した時の出力結果 の時とで出力結果が異なるのでしょうか?
その理由は MyCalc.py
の実行の仕方の違いにあります。
直接スクリプトを実行した時の出力結果 の時は、MyCalc.py
を python
コマンドで直接実行していました。そして、その結果 __name__
の出力結果が '__main__'
となっていました。
それに対し、今回は MyCalc.py
を MyMain.py
から import
することによって実行しています。この MyCalc
は import
時に指定された モジュール名
となります。そして、その結果、__name__
の出力結果が 'MyCalc'
となりました。
つまり、スクリプトが python
コマンドで直接実行された場合、__name__
は '__main__'
の文字列を参照することになります。
それに対し、他のスクリプトから import
されて実行された場合、__name__
は 'モジュール名'
の文字列を参照することになります。
では、ここで先ほどの実行結果における2回目の __name__
の出力内容を確認してみましょう!この 2回目の __name__
の出力は MyMain.py
から実行されており、この出力結果は先ほどの MyMain.py
実行結果の下記部分となります。
__main__ START!
MyMain.py
は python
コマンドによって直接実行されているため(python ファイル名.py
によって実行されているため)、__name__
は '__main__'
を参照しており、__name__
の出力結果は上記のように '__main__'
となります。
スポンサーリンク
__name__
が参照する文字列
ここまで確認してきたように、__name__
はスクリプトの「実行のされ方」に応じて下記を参照する変数となります。
import
されて実行された場合:'モジュール名'
python
コマンドで直接実行された場合:'__main__'
また、import
されて実行されるということは、そのスクリプトがモジュールとして利用されていることになります。したがって、上記の2つの場合分けは、スクリプトがモジュールとして利用されるかどうかの観点で下記のように書き換えることもできます。
- モジュールとして利用されているスクリプトの場合:
'モジュール名'
- モジュールとして利用されていないスクリプトの場合:
'__main__'
おそらく、if __name__ == '__main__'
のメリットを理解する上では、上記のモジュール利用の観点での __name__
の意味合いで考えた方が分かりやすいと思います。
if __name__ == '__main__'
とは
__name__
の変数の役割ができれば、if __name__ == '__main__'
の意味合いも簡単に理解できると思います。
前述の通り、__name__
は下記を参照する変数となります。
- モジュールとして利用されているスクリプトの場合:
'モジュール名'
- モジュールとして利用されていないスクリプトの場合:
'__main__'
したがって、if __name__ == '__main__'
とは、この if
文を記述しているスクリプトが「モジュールとして利用されていない」ことを判断するための条件文であると言えます。
ですので、if __name__ == '__main__'
が成立する場合、このスクリプトは「モジュールとして利用されていない」と判断することができます。
逆に if __name__ == '__main__'
が成立しない場合、もしくは if __name__ != '__main__'
が成立する場合、このスクリプトは他のスクリプトから「モジュールとして利用されている」と判断することができます。
つまり、下記のように条件分岐を行えば、モジュールとして利用されていない場合のみ(python
コマンドによって直接実行されている場合のみ)、特定の処理 を実行することができるようになります。
if __name__ == '__main__':
特定の処理
また、下記のように条件分岐を行えば、他のスクリプトからモジュールとして利用されている場合のみ、特定の処理 を実行することができるようになります。
if __name__ != '__main__':
特定の処理
もちろん、両方の場合を考慮して下記のように条件分岐を行なっても良いです。
if __name__ == '__main__':
モジュール利用されていない場合のみ実行したい処理
else:
モジュール利用されている場合のみ実行したい処理
if __name__ == '__main__'
を利用するメリット
では、if __name__ == '__main__'
を利用するメリットは何なのでしょうか?
このメリットは、if __name__ == '__main__'
の意味合いからも分かるように、モジュールとして利用されているかどうかによってスクリプト実行時の動作を切り替えることができるようになる点にあります。
スポンサーリンク
利用しやすいモジュールを実現できる
ご存知の通り、Python では import
によって他のモジュールで定義された機能(関数やクラス)を利用することができるようになります。
ほとんどの場合、import
する目的は、import
するモジュールで定義された関数やクラスを利用することであると言えると思います。
それに対し、モジュールの作り方によっては、import
すると関数やクラスの定義の読み込みだけでなく、処理の実行までされてしまうような場合があります。
前述の MyCalc.py
がまさにそれで、import MyCalc
を行うことで add
・sub
・mul
・div
の4つの関数が利用できるようにもなるのですが、それに追加して import
時に下記の処理まで実行されてしまいます。
print(__name__ + ' START!')
print(add(5, 2))
print(sub(5, 2))
print(mul(5, 2))
print(div(5, 2))
ですので、add
・sub
・mul
・div
を利用することのみを目的に import MyCalc
を実行した場合、import
時に上記の処理まで実行され、無駄な処理・出力が行われてしまうことになります。
このように、モジュール利用時には実行されない方が良い処理が存在する場合、if __name__ == '__main__'
を利用することで、そういった処理をモジュールとして利用されている場合のみスキップするようにすることができます。
例えば MyCalc.py
の例であれば、上記の5行の処理を次のように if __name__ == '__main__'
が成立する場合のみ実行するようにしてやれば、import
されて他のスクリプトからモジュールとして利用される場のみ、これらの処理をスキップするようにすることができます。
def add(x, y):
return x + y
def sub(x, y):
return x - y
def mul(x, y):
return x * y
def div(x, y):
return x / y
if __name__ == '__main__':
print(__name__ + ' START!')
print(add(5, 2))
print(sub(5, 2))
print(mul(5, 2))
print(div(5, 2))
こうすることで、import
時に無駄な処理が行われないようになり、利用しやすいモジュールとして仕立てることができます。
もちろん、下記のように if __name__ == '__main__'
成立時に実行される処理を main
関数として切り出し、if __name__ == '__main__'
成立時に main
関数の呼び出しのみを行うようにしても良いです。
def add(x, y):
return x + y
def sub(x, y):
return x - y
def mul(x, y):
return x * y
def div(x, y):
return x / y
def main():
print(__name__ + ' START!')
print(add(5, 2))
print(sub(5, 2))
print(mul(5, 2))
print(div(5, 2))
if __name__ == '__main__':
main()
この形式が if __name__ == '__main__'
の利用例としては一番ポピュラーだと思いますが、別に if __name__ == '__main__'
成立時に実行される処理を関数として切り出したり、関数名を main
とすることは必須ではありません。
重要なのは、モジュールとして利用されているかどうかによって動作を切り替えることです。ただ、上記の形式は見慣れている方も多いと思いますので、慣例に倣って上記の形式で記述してあげる方が無難だと思います。
モジュールの単体テストが実現できる
無駄な処理なのであれば、わざわざ if __name__ == '__main__'
を利用しなくても削除してしまえば良いと思われる方もいるかもしれません。
もちろんそういったケースもあると思いますが、モジュールとして利用されない場合に意味のあるものとなる処理もあり、この場合は if __name__ == '__main__'
を利用した方が良いと思います。
その処理の具体例としては、モジュールで定義された関数やクラスの動作確認を行う処理が挙げられると思います。要はモジュールの単体テストです。
いくら関数やクラスの提供を行うことを目的としたモジュールを開発するといっても、それらの関数やクラスの動作確認は行うはずです。
そういった、モジュールの動作確認を行う際の処理を同一スクリプト内に記述したい場合は if __name__ == '__main__'
の利用が効果的です。if __name__ == '__main__'
が成立する場合のみモジュールの単体テストが実行されるようにしておけば、python
コマンドによって直接実行された場合のみモジュールの単体テストが実行されるようになります。
こうしておくことで、モジュール開発者はモジュールのスクリプトを python
コマンドで直接実行することで動作確認を行うことができ、モジュール利用者は import
で実行することで動作確認という不要な処理をスキップすることができるようになります。こんな感じで、if __name__ == '__main__'
を利用することでスクリプトの実行の仕方によって動作を切り替えることができます。
例えば、利用しやすいモジュールを実現する の最後に紹介した MyCalc.py
では、関数を実行する処理(関数の動作確認を行う処理)が if __name__ == '__main__'
が成立する場合のみ実行されるようになっているため、動作確認を行いたい場合は python
コマンドで直接実行してやれば良いことになります。
また、下記のように MyCalc.py
を書き換えれば、python
コマンドで実行した場合のみ関数内の print
が実行されるようになります。したがって、モジュールとして利用される時の動作に(ほぼ)影響を与えることなく、モジュールの単体テスト時に詳細な動作確認を行うことができるようになります。
def add(x, y):
if DEBUG_MODE:
print('引数:', x, y)
return x + y
def sub(x, y):
if DEBUG_MODE:
print('引数:', x, y)
return x - y
def mul(x, y):
if DEBUG_MODE:
print('引数:', x, y)
return x * y
def div(x, y):
if DEBUG_MODE:
print('引数:', x, y)
return x / y
def main():
print(__name__ + ' START!')
print(add(5, 2))
print(sub(5, 2))
print(mul(5, 2))
print(div(5, 2))
if __name__ == '__main__':
DEBUG_MODE = True
main()
このように、if __name__ == '__main__'
はモジュールとして利用されたかどうかによって実行される処理を切り替える際に有効であり、特に有効な処理としてはモジュールで定義する関数やクラスの動作確認(モジュールの単体テスト)が当てはまると思います。
想定外の使い方をされている場合に警告出力できる
また、if __name__ == '__main__'
を利用することで、自身が作成したスクリプトが「想定外の使い方」をされている場合に警告を出力するようなことも可能となります。
これにより、「モジュールとして利用されることを想定しているスクリプト」が python
コマンドで直接実行されたような場合に警告を出力するようなことができます。そして、それによってスクリプト利用者に正しい使い方を示すことができ、より使いやすいスクリプト・モジュールに仕立てることができます。
例えば、MyCalc.py
を下記のように変更してやれば、import
されずに python
コマンドで実行された際には警告が出力されるようになり、利用者に正しい使い方を示すことができます。
def add(x, y):
return x + y
def sub(x, y):
return x - y
def mul(x, y):
return x * y
def div(x, y):
return x / y
if __name__ == '__main__':
print('このスクリプトはimportして使用してください')
スポンサーリンク
if __name__ == '__main__'
の使いどころ
最後に、どんな時に if __name__ == '__main__'
を利用すれば良いのかについて解説しておきます。
ここまで解説してきたように、if __name__ == '__main__'
はモジュールとして利用される場合とそれ以外の場合とで場合分けを行う際に有効な条件分岐となります。
ですので、特にモジュールとして利用されることを見据えて作成するスクリプトにおいては、if __name__ == '__main__'
を利用して適切な場合分けを行うようにした方が良いと思います。
ただ、最初はモジュールとして利用されることを見据えていないようなスクリプトであっても、そのスクリプトで定義した関数を後から他のスクリプトから import
して利用したくなるような場合も多々あります。
そういった場合のことを考えると、とりあえず if __name__ == '__main__'
を使ってモジュールとして利用される場合とされない場合とで適切に動作を切り替えられるようにしておいた方が無難だと思います。こうしておくことで、モジュールとして利用される予定のなかったスクリプトであっても、後からスムーズにモジュールとして利用できるようになります。
ということで、結局、関数定義やクラス定義を行うスクリプトであれば、とりあえず if __name__ == '__main__'
を利用しておいた方が良いと言えると思います。
ただ、上記のようなことは if __name__ == '__main__'
に限った話ではなく、関数やクラスの作り方にも言える話です。
後からモジュールとして利用されることがあることを考慮して、モジュールとして利用しやすいように関数やクラスも作った方が良いです。
こうすることで、後から自分が作ったスクリプトをモジュールとした再利用しやすくなり、開発効率を向上させることができます。
if __name__ == '__main__'
はモジュールとして利用しやすいスクリプトを作成するための手段の一つに過ぎず、if __name__ == '__main__'
を使いこなすことよりもスクリプト全体としてモジュール利用しやすい記述を心がけることが重要だと思います。
まとめ
このページでは、Python における if __name__ == '__main__'
の意味合いについて説明しました。
__name__
は Python インタプリタによって自動的に用意される変数であり、スクリプトの使い方によって下記のように参照する文字列が変化します。
- モジュールとして利用されているスクリプトの場合:
'モジュール名'
- モジュールとして利用されていないスクリプトの場合:
'__main__'
したがって、if __name__ == '__main__'
は、この条件分岐を行なっているスクリプトがモジュールとして利用されていないかどうかを判断するものであると考えることができます。
具体的には、条件が成立する場合はモジュールとして利用されていない、すなわち python
コマンドで直接実行されていると判断することができます。逆に条件が成立する場合、そのスクリプトはモジュールとして利用されていると判断することができます。
そして、この判断を行うことで、モジュール利用されているかどうかによってスクリプト実行時の動作を変化させるようなことができます。例えば、モジュール利用されている場合に無駄な処理をスキップするようなことも可能ですし、想定されていない使い方をされている際に警告表示をするようなことも可能です。
if __name__ == '__main__'
を利用することで、より使いやすいモジュールを実現することが可能となりますので是非積極的に利用してみてください!
また、if __name__ == '__main__'
の利用だけでなく、関数やクラスを作る際にもモジュールとして利用しやすいものを作るように心がけると良いと思います!