質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • Python 3.x

    6316questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • TensorFlow

    667questions

if __name__ == '__main__': の必要性

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 1,008
退会済みユーザー

退会済みユーザー

if name == 'main': の必要性がわかりません。

# coding: utf-8

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import time
import tensorflow as tf

import model as model

from reader import Cifar10Reader

FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_integer('epoch',30,"訓練するEpoch数")
tf.app.flags.DEFINE_string('data_dir','./data/',"訓練データのディレクトリ")
tf.app.flags.DEFINE_string('checkpoint_dir','./checkpoints/',"チェックポイントを保存するディレクトリ")

filenames = [
    os.path.join(FLAGS.data_dir,'data_batch_%d.bin' % i) for i in range(1,6)
]


def main(argv=None):
    train_placeholder = tf.placeholder(tf.float32,shape=[32,32,3],name='input_image')
    image_node = tf.expand_dims(train_placeholder,0)

    logits = model.inference(image_node)

    with tf.Session() as sess:
        sess.run(tf.initialize_all_variables())

        total_duration = 0

        for epoch in range(1,FLAGS.epoch+1):
            start_time = time.time()

            for file_index in range(5):
                print('Epoch %d: %s' % (epoch,filenames[file_index]))
                reader = Cifar10Reader(filenames[file_index])

                for index in range(10000):
                    image = reader.read(index)

                    logits_value = sess.run([logits],feed_dict={
                        train_placeholder:image.byte_array,
                    })

                    if index % 1000 ==0:
                        print('[%d]: %r'% (image.label,logits_value))

            reader.close()

            duration = time.time() - start_time
            total_duration += duration

            print('epoch %d duration = %d sec'%(epoch,duration))

            tf.train.SummaryWriter(FLAGS.checkpoint_dir,sess.graph)
        print('Total duration = %d sec'% total_duration)

if __name__ == '__main__':
    tf.app.run()


というCIFAR-10形式のデータセットを推論するプログラムを書きました。
このコードの最後に

if __name__ == '__main__':
    tf.app.run()


という記述がありますが、この記述の必要性がわかりません。
http://azuuun-memorandum.hatenablog.com/entry/2015/05/09/002549
の記事を読んで、if name == 'main':
メソッドの機能はわかりました。(トップレベルファイルで実行された時にのみ、テスト用の値出力処理が行われるようにすることができる 事)
しかし、この記述がこのコードの一番下で必要な理由がわかりません。
どうしてこの記述は必要なのでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

結論から言いますと、モジュールの直接実行をサポートする場合はif name == 'main':を明示的につけておくのが良い習慣です。
出力自体は変わらないケースでも、とりあえず付けておくという方が多いと思います。

例えば以下の2つのコードがあります。
if name == 'main':を利用しているタイプと、していないタイプです。

def main():
    print('何か処理')

if __name__ == '__main__':
    main()
def main():
    print('何か処理')

main()

if name == 'main':がついている方は、python file.pyのように実行することでmain関数が呼ばれます。モジュールを直接実行することをサポートする場合は、これをつけることで明示的に示すことが可能です。(この明示的に、というのはPythonのZENでもあります。)

後者のタイプもpython file.pyのように実行することでも呼ばれますが、あくまで「モジュールが読み込まれたら」main関数が実行されます。

上の例では結果的に同じ出力となりますが、コードを拡張しようとすると後者は問題が発生します。
直接実行をサポートしつつ、他モジュールからimportして任意のタイミングで使えるようにしたいと思うと、結局のところ前者の書き方にせざるをえません。それならば、最初から前者の書き方にしておくのが無難です。

後者の書き方をするケースは、モジュールが読み込まれたタイミングで自動的に関数を実行したい場合です。例えば、そのモジュールのセットアップ処理なんかが当てはまります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/12 19:19

    ありがとうございます。質問なのですが、コードを拡張しようとすると後者は問題が発生します。
    直接実行をサポートしつつ、他モジュールからimportして任意のタイミングで使えるようにしたいと思うと、結局のところ前者の書き方にせざるをえません。
    のところで、例えば
    import メインメソッドを書いたファイル名
    ~
    ~
    ~
    メインメソッドを書いたファイル名.main()
    と書けばmain()メソッドは実行できませんか?
    なぜ、コードを拡張しようとすると後者は問題が発生するのかわからなくて。。。

    キャンセル

  • 2017/04/12 19:35

    後者の書き方は、
    import メインメソッドを書いたファイル名
    の時点でmain関数が呼ばれることに注意です。

    メインメソッドを書いたファイル名.main()
    でも当然呼べますが、この書き方で呼ぶ前のモジュールインポートの時点でも一度呼ばれており、そのことを踏まえる必要が出てきます。
    そして、このモジュールのインポート時というのは中々タイミングが計づらく、それならば前者の書き方にし、呼び出すを行う場合は
    メインメソッドを書いたファイル名.main()
    で統一するほうが分かり易いです。

    キャンセル

+1

試しに一番上に書いてみるとエラーになることが観察できると思います。

pythonは書いたものが上から下へ順番に実行されますが、defで関数を宣言する以前にはその関数は呼び出せません。

そういう訳で全ての関数定義などを書いた後に一番下に書くのだと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/13 17:12

    順番に実行されるのはそのとおりですが、 `if name == 'main': ` の必要性とは関係が無い。

    キャンセル

  • 2017/04/13 18:03 編集

    質問者さんは
    > ...(トップレベルファイルで実行された時にのみ、テスト用の値出力処理が行われるようにすることができる 事)
    > しかし、この記述がこのコードの一番下で必要な理由がわかりません。
    と書いているので このような回答をしました。
    ---
    正直いえば質問者さんがどこまでわかっているか正確に把握するのは難しいのですが、一応回答になっていはいると考えたわけです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python 3.x

    6316questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • TensorFlow

    667questions