おぼえがき

過ちては則ち改むるにうんぬんかんぬん

__name__と__main__を使ったコードの記述について(Python)

f:id:feci:20210726231508j:plain

Python3

 

Python3.8.5における__name__と__main__を使ったコードの記述について。

import lesson_package.deep.utils02
import config

def main():                   #__main__のときに実行したい処理
  print('hellow:'__name__)

if __name__ == '__main__':    #__main__のときだけ実行
  main()                      #こうやって実行するとimportされても安心

 

Pythonでは上記スクリプトのようにモジュールをimportした場合、そのモジュールに書かれている処理がいま実行したモジュールよりも先に勝手に実行されてしまいます。

 

例えばconfig.pyに print('おなかへった'); という記述があるとします。

するとそのconfig.pyをimportしたこのモジュールを実行すると、このモジュールのスクリプトよりも先に勝手に「おなかへった」と出力されてしまうのです。

 

このimport先でのスクリプト暴発問題を解決するための手段が、__name____main__の活用です。

 

 

Pythonprint(__name__); と記述して実行すると、__main__と表示されます。

ではこのモジュールで2行目にimportしているconfig.pyにも同じ print(__name__); と記述して、その処理をこっちのimportしたモジュールで実行するとどうなるでしょうか。

 

表示されるのは__main__ではなく、configというimport文に記述した文字列になります。

これは、例えば上記スクリプトの1行目でimportしているutils02.pyでも同様の結果になります。

 

つまりutils02モジュールに print(__name__); と記述してからこっちのimportしたモジュールを実行すると、表示されるのはやはりimport文と同じ lesson_package.deep.utils02 という文字列となります。

 

この__name__と__main__の仕様を利用することで、各モジュールの処理を、もしどこか別のモジュールにimportされたとしてもimport先で処理が暴発しないようなセーフティー機構を作ることができます。

 

 

上記のスクリプトは、まさにそのセーフティーの形になっています。

つまりこのモジュールが__main__のときに実行したい処理をすべてユーザー定義関数のmainにまとめておき、if文で条件を __name__ == '__main__': としてやることで、その処理はimport先では勝手に実行されなくなります。

 

さっき確認したとおり、__name__が__main__になるのはそのモジュールを直接実行したときだけですからね。

import先で実行される場合は、このモジュールの__name__は__main__にはなりません。

 

実際のPythonの開発では、すべてのモジュールにこの__name__と__main__を使ったセーフティー機構を用意しておくことが推奨されているようです。

 

 

__name__と__main__を使ったセーフティー機構の定形は以下のとおりです。

 

def main():
    このモジュールで実行したい処理

 

if __name__ == '__main__':
    main()

 

 

以上です。