#Pythonを勉強していたらおまじないにぶち当たってしまいました。
**if __name__ == '__main__'**というおまじない、Pythonをある程度勉強したひとは出会った事があると思います。
そんなに使い方が難しいわけではないおまじないですが、初見では仕組みがよくわからずモヤモヤしていました。
私は仕組みがよくわからないものを使うのは苦手です。
このおまじないについてはすでに色々な解説がQiitaにもあります。
特に
[Python] if __name__ == '__main__' について理解しよう
はとても参考になりました。
ただ、まだしっくりしないモヤっとした感じがありました。
そこで、**__name__や__main__**の挙動を自分なりにコードを書いて調べてみました。
以下のコードを書いて実行してみます
print(__name__)
結果はこうなります
__main__
このduname.pyをモジュールとして他のスクリプトからimportしてみましょう
import duname
結果はこうなります
duname
公式ドキュメントにも書かれていますが、
__name__
はスクリプトから直接実行されたときは文字列
'__main__'
が代入され、モジュールとして読み込まれた場合には
モジュール名が代入されます。
そういうわけで
if __name__ == '__main__'
の下に書かれたコードはスクリプトから直接実行された時は読まれるけど、モジュールとして呼び出した時には読まれないという効果が得られます。
##もしかして**__main__.py**って名前のスクリプトを書いたらバグって常に実行されるようになるんじゃね?
早速以下のコードを書いた
def printhello():
print('hello')
if __name__ == '__main__':
printhello()
モジュールとして呼び出します
from __main__ import printhello
ImportError: cannot import name 'printhello'
とエラーが出てしまいました。
別の書き方を試してみます
import __main__
printhello()
NameError: name 'printhello' is not defined
とエラーが出ます。
「えー、__main__.pyで定義してあるじゃん!?」
どうやら**__main__**は特別なモジュールで、読み込まれる時に初期化されるみたいです。
というわけでバグは起きないのでした(当然といえば当然)。
##まとめ
・**__name__はスクリプトを直接実行した時は'__main__'**が代入され、モジュールとして呼び出された時はモジュール名が代入される。
・if __name__ == '__main__'の下に書かれたコードはモジュールとして呼び出された時は実行されない。
・__main__.pyを作って呼び出しても初期化されてしまう。
まだまだよくわからないところはありますが、自分としてはおまじないの仕組みが大体わかってモヤモヤはなくなりました。
すでに色々なところに書かれている内容の繰り返しなので、この記事には価値があまりありませんが、
こうやってまとめる事で自分の中の理解が深まりました。
なので、これからもこうした記事を増やしていきたいと思っています。