Python __name__ __main__

Python学習【365日チャレンジ!】75日目のマスターU(@Udemy11)です。

最近、若い子と話す機会があって、

マスターU

Facebookやってるの?

って聞いたら、もちろん答えは

青年

やってません。

で、次に

マスターU

Twitterは?

って聞いたら、

青年

SNSはやってません

って答えだったので

マスターU

LINEはやってるの?

と聞いたら、

青年

LINEもやってません

ということで、その先の「友達いる?」って質問は聞くことができませんでした。

今どき、そんな子もいるんですね。

それでは、今日も元気にPython学習を始めましょう!

昨日の復習

昨日は、ライブラリをインポートする際の記述の仕方について学習しました。

import collections
import os
import sys

import termcolor

import session

import day0423

記述する順番は、

  1. 標準ライブラリ
  2. サードパーティーライブラリ
  3. 自作パッケージ
  4. モジュール(pythonファイル)

の順で、一行あけて、それぞれのグループ内でアルファベット順に並べました。

この並びにすることで、標準ライブラリから読み込んでいるのか、サードパーティーから読み込んでいるのか、自分で作ったパッケージやモジュールなのかというのが一目瞭然になり、自分以外の人もコードがわかりやすくなるということでした。

ルールに従った記述をして、きれいなPythonコードを極めましょう!

では、本日の学習に入りたいとおもいます。

__name__とは

__name__は、簡単に言うとファイルのポジションの名前のことで、importで読み込まれるときは、階層を含んだPythonファイルの名前で、直接実行しているファイルの場合は__main__になります。

session ┳ lesson.py
        ┗ lesson_package ┳ utils.py
                          ┗ __init__.py

なので、上記のようなファイル階層で、lesson.pyutils.pyが読み込まれている場合の__name__はそれぞれ次のようになります。

lesson.py = __main__

utils.py = lesson_package.utils

実際に、コードを書いて__name__を出力してみます。

lesson.py

from lesson_package import utils

print(__name__)
print(utils.__name__)

出力結果

__main__
lesson_package.utils

読み込まれている場合は階層+ファイル名になるということです。

ただ、utils.pyを読み込まないで直接実行した場合の__name____main__になるので、ちょっとややこしいんですよね。

__main__って?

__main__というのは、Pythonファイルをメインで実行している場合の名前です。

つまり、読み込んで利用しているファイルではなく、このファイルがメイン、つまり、

あんたが大将!

ってことですね。

Pythonでは、メインで実行するファイルも、パーツとして作られたパッケージにあるファイルもすべて単体で実行することができますし、importで読み込むこともできます。

なので、どのファイルも__name____main__になることがあるし、読み込まれて__name__が階層+ファイル名になることがあります。

そして、読み込まれているファイルなのか、直接実行しているファイルなのかを判断することは非常に重要なんです。

読み込まれた時点で実行される

これまでは、読み込むファイルもメインで実行するファイルも同じように関数やprint出力を記述してきましたが、importされた時点で、読み込んだモジュール(ファイル)が実行されているというイメージは持っていなかったと思います。

どういうことかとういと、メインのファイルから関数が呼び出されてはじめてモジュールが実行されているイメージだったと思います。

例えば次ののファイル階層で、lesson.pyutils.pyimportされていたとします。

session ┳ lesson.py
        ┗ lesson_package ┳ utils.py
                          ┗ __init__.py

lesson.py

from lesson_package import utils

r = utils.say_word()
print(r)

utils.py

def say_word():
    return 'This is it.'

print('end')

この状態で、lesson.pyを実行すると、say_word()の行ではじめてutils.pyが実行されて、This is it.が返され、utils.pyに記述されているprint('end')は、関数が実行されたあとに出力されるような感じですよね。

しかし実際は、lesson.pyimport utilsの行ですでにutils.pyが実行されて、print('end')endが出力されます。

なのでlesson.pyを実行したときの出力結果は、次のようになります。

end
This is it.

普通にutils.pyを実行するときとおなじように、lesson.pyutils.pyを読み込んだ時点で、print('end')endが出力されます。

そしてその後lesson.pyによって、This is it.が出力されるわけです。

なので、関数以外の実行コードを記述する場合は注意が必要なんです。

__main__の判断

単体で実行するときには出力したいけど、読み込まれたときに実行したくないときの書き方があります。

それが、Pythonファイルの__name____main__なのか判断して、__main__だった場合に実行するという書き方です。

先に上げた例で、utils.pyの場合、次のようになります。

utils.py

def say_word():
    return 'This is it.'

if __name__ == '__main__':
    print('end')

lesson.pyは同じコードで、lesson.pyを実行した場合に、endが出力されません。

なので、もしモジュールとして読み込まれたときに実行されたくない場合は、

if __name__ == '__main__':

を使うようにしましょう。

main()を使う

さらに、自分が作成したパッケージで、メインで実行しているファイルも、誰かに読み込まれることがある可能性を考えて、読み込まれた時点で、いきなり実行されないようにする必要があります。

例えば、これまでの例と同じファイル階層で、それぞれのファイルが次のような場合を考えてみます。

lesson.py

from lesson_package import utils

utils.say_word()

utils.py

def say_word():
    print('Good morning!')

この場合、lesson.pyが読み込まれると、自動的にsay_word()が実行されて、Good morning!が出力されてしまいます。

なので、この場合は、say_word()main()関数として定義して、lesson.py__name____main__の場合に、main()を実行するというコードの書き方をします。

lesson.pyの記述方法

from lesson_package import utils

def main():
    utils.say_word()

if __name__ == '__main__':
    main()

出力結果

Good morning!

人に読み込まれることが全く無いファイルだとしても、このように書く癖をつけておけば、のちのち役に立つので、面倒ですが、きちんと書くように心がけておきましょう。

ぐいぐい上がる

いよいよ実践的なコードの書き方に入ってきたか!という感じがしますが、自分自身の中身がスカスカな気がしています。

これまでは基礎的な部分を学習しているものの、具体的な使い方がまだまだ見えていないので、きちんとは身についていません。

なので、しっかりと復習しながら、使い方を覚えていく必要があるのですが、やはり実践で使うのがPythonマスターへの一番の近道のような気がします。

とはいえ、今はどんなサービスが作りたいのか具体的には見えてきていないのと、それをやりだすとこれまでのように、中途半端な憶え方になって、結局時間が経てば、身についていないなんてことになってしまうので、しっかりと身につけられるように、基礎基本をじっくり学んでいこうと思います。

どんどんレベルアップしていく酒井さんの講座ですが、理解できないことがレクチャーに入ってくるので、そのたびに止めては内容を確認し、わからない場合はネットで調べるという方法をとっています。

Udemy講師 酒井さん プログラミング Python

これがいいのか悪いのかは別として、一歩一歩進んでいることは間違いないので、これからもしっかり理解しつつ講座を進めていこうと思っています。

それでは、明日もGood Python!