web-dev-qa-db-ja.com

なぜdef main()を使うのですか?

可能な重複:
if __name__== "__main__"は何をするのですか?

私はいくつかのコードサンプルとチュートリアルを見ました

def main():
    # my code here

if __== "__main__":
    main()

しかし、なぜ?ファイルの先頭に関数を定義しないで、その下にコードを書くだけの理由がありますか?すなわち

def my_function()
    # my code here

def my_function_two()
    # my code here

# some code
# call function
# print(something)

私は主に何か韻があるのだろうか?

515
Wizzard

メインセンチネルがなければ、スクリプトがモジュールとしてインポートされたとしてもコードは実行されます。

586

他の誰もがすでにそれに答えています、しかし私はまだ追加する何かがあると思います。

そのifステートメントがmain()を呼び出す理由(順不同):

  • 他の言語(CやJavaなど)には、プログラムが実行されたときに呼び出されるmain()関数があります。このifを使うことで、私たちはPythonをそれらのように振る舞わせることができます。

  • コードは clean になり、読みやすく、整理されたものになります。 (ええ、私はこれが主観的であることを知っています)

  • そのPythonコードを厄介な副作用のないモジュールとしてimportすることは可能でしょう。

    • これは、そのコードに対してテストを実行することが可能になることを意味します。

    • つまり、そのコードを対話型のPythonシェルにインポートしてテスト/デバッグ/実行することができます。

  • def mainの内側の変数はlocalですが、外側の変数はglobalです。これにより、いくつかのバグと予期しない動作が発生する可能性があります。

しかし、あなたはmain()関数を書き、それをifステートメントの中で呼び出すのは必須ではありませんです。

私自身は通常、どんな機能も持たない小さな使い捨てのスクリプトを書き始める。スクリプトが十分に大きくなった場合、またはそのようなコードをすべて関数の中に入れておくと便利な場合は、コードをリファクタリングして実行してください。これはbashスクリプトを書くときにも起こります。

Main関数の中にコードを置いても、それを正確に記述する必要はありません。きちんとしたバリエーションは次のようになります。

import sys

def main(argv):
    # My code here
    pass

if __== "__main__":
    main(sys.argv)

つまり、カスタムパラメータを渡して他のスクリプト(または対話型シェル)からmain()を呼び出すことができます。これは、単体テストやバッチ処理で役立ちます。しかし、上記のコードではargvの解析が必要になることを忘れないでください。そのため、すでに解析されたパラメータを渡す別の呼び出しを使用したほうがよいでしょう。

私が書いたオブジェクト指向アプリケーションでは、コードは次のようになりました。

class MyApplication(something):
    # My code here

if __== "__main__":
    app = MyApplication()
    app.run()

だから、あなたにぴったりのコードを書いてください。 :)

226

foo.pyの内容

print __name__
if __== '__main__':
    print 'XXXX'

ファイルfoo.pyは2つの方法で使用できます。

  • 別のファイルにインポートした場合:import foo

この場合、__name__fooであるため、コードセクションは実行されず、XXXXも出力されません。

  • 直接実行された場合:python foo.py

直接実行されると、__name____main__と同じになり、そのセクションのコードが実行されてXXXXが出力されます。

同じモジュール内でさまざまな種類のユニットテストを書くためのこの機能の使用の1つ。

88
pyfunc

" if __name__==“__main__”:は何をしますか "はすでに答えています。

main() function を持つことで、モジュールをimportにした場合にその機能を呼び出すことができます。これ(IMHO)の主な(駄目なのではない)利点は、それを単体テストできるということです。

17
Johnsyweb

2番目のスクリプトを考えてください。別のものにインポートすると、「グローバルレベル」の場合と同様の手順が実行されます。

7
Noe