Python

Python初学者向け:__name__と__main__について基本から解説します

スポンサーリンク

 

この記事はこんな方におススメです
  • Pythonを始めたばかりで基本から学びたい方
  • Pythonの基本的な部分を速習してまずは全体像を把握しておきたい方

はじめに

今回は「__name__」属性を扱います。Pythonのプラグラムを読んでいると、「if __name__ == ‘__main__’ :」という記述を目にしたことがあるのではないでしょうか?これ、初めて見るとなんのことだかさっぱりわからないですよね。今回は、この意味を基本から解説していきます。

モジュールをインポートするとその__name__属性にモジュールの名前が文字列として格納される。<モジュール名>.__name__で取得できる。

モジュールを呼び出して実行する

関数や変数、クラスを定義したモジュールを他のスクリプトから参照できるように、モジュールをインポートすることがあります。モジュールを作成している段階では必要なコードも、スクリプトから参照した時には不要であることがあります。

「if __name__ == ‘ __main__’ :」は一言で言うと、直接コールされたか、インポートされたかを判定する役割を担っています。詳しく見ていきましょう。

直接実行される場合とインポートされる場合で制御する

準備

準備としてmain.pyとtestmodule.pyを用意しましょう。まず、testmodule.pyには次のように関数を定義しておきましょう。

(testmodule.py)

def say_hello():
    print('Hello')

このモジュールを作っているときであれば、実際に定義した関数を呼び出して確認することもありますよね。次のような感じです。

testmodule.py

def say_hello():
    print('Hello')

say_hello()

このモジュールを直接実行すると、まず関数「say_hello()」が定義されて、その後にsay_hello()が実行されて「Hello」が表示されます。これは期待通りの動きですね。

次にmain.pyでこのモジュールを呼び出してみましょう。

main.py

import testmodule

main.pyを実行してみましょう。結果は予想できましたか?「testmodule」をインポートしただけなのに「Hello」を表示されました。これは、testmoduleがインポートされたときに、testmodule.pyが実行されるからです。そのため、testmodule.pyのトップレベルに記載のあるprint文が実行されたわけですね。このようにモジュール開発時には必要なコードでも、参照するときには不要なコードがあります。これを制御するのが「if __name__ == ‘__main__’ :」です。

__name__属性

Pythonには「__name__」という特殊な変数があります。この挙動を確認していきましょう。まずはtestmodule.pyを次のように書き換えましょう。

testmodule.py

def say_hello():
    print('Hello')

say_hello()
print(f'testmodule.__name__:{__name__}')

これを実行すると最後のprint文の部分は、「testmodule.name:main」と表示されたかと思います。次にmain.pyでtestmoduleを呼び出したときの「__name__」をみてみましょう。main.pyを実行してみます。

どうでしょうか?「testmodule.name:testmodule」と表示されましたね。これは次のようになっています。

  • __name__が属しているスクリプトがコールされて実行された場合は「__main__」
  • インポートされた場合は「__モジュール名__」

この__name__属性の性質をうまく使えば、直接呼び出されたときにのみ実行する、のような制御ができますね。

__name__属性による制御

ここまでくると簡単ですね。モジュールが直接呼び出されたときは「__name__」は「__main__」であり、インポートされたときは「__モジュール名__」が入るのでした。そのため、直接呼び出されたときのみ実行したいコードは、「__name__」が「__main__」のときに実行するようにすればよいわけです。これが冒頭で出てきたif文です。testmodule.pyを次のように書き換えましょう。

testmodule.py

def say_hello():
    print('Hello')

if __name__ == '__main__':
    say_hello()
    print(f'testmodule.__name__:{__name__}')

こうすることで、5~6行目はインポートされたときには実行されなくなりました。

スポンサーリンク

まとめ

今回は「__name__」属性について扱いまいした。モジュールが直接呼ばれるときにのみ実行したいコードがあるときには、この「__name__」属性を使って制御できることを説明しました。

コメント

タイトルとURLをコピーしました