はじめに
今回は「__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__属性の性質をうまく使えば、直接呼び出されたときにのみ実行する、のような制御ができますね。
__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__」属性を使って制御できることを説明しました。
コメント