意味 python __name__ == "__main__"の場合はどうなりますか?




13 Answers

スクリプトをコマンドとしてPythonインタプリタに渡すことでスクリプトを実行すると、

python myscript.py

インデントレベル0にあるすべてのコードが実行されます。 定義されている関数とクラスは、よく定義されていますが、コードは実行されません。 他の言語とは異なり、 main()関数は自動的に実行されません。main main()関数は暗黙的に最上位レベルのすべてのコードです。

この場合、最上位コードはifブロックです。 __name__は、現在のモジュールの名前を評価する組み込み変数です。 しかし、モジュールが直接実行されている場合(上記のmyscript.pyように)、代わりに__name__が文字列"__main__"設定されます。 したがって、あなたのスクリプトが直接実行されているのか、テストによって他のものによってインポートされているのかをテストすることができます

if __name__ == "__main__":
    ...

スクリプトが別のモジュールにインポートされている場合、そのさまざまな関数とクラス定義がインポートされ、そのトップレベルコードが実行されますが、上記のif節のbody内のコードは条件として実行されません満たされていない。 基本的な例として、次の2つのスクリプトを考えてみましょう。

# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

今、あなたがインタプリタを

python one.py

出力は次のようになります。

top-level in one.py
one.py is being run directly

代わりにtwo.pyを実行すると:

python two.py

あなたは得る

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

したがって、モジュールoneがロードされると、その__name__"__main__"ではなく"one"に等しくなります。

python main 実行

if __name__ == "__main__":は何ですか?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while True:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)

if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))



if __name__ == "__main__":は何ですか?

基本を概説するには:

  • プログラムへのエントリポイントであるモジュール内のグローバル変数__name__は、 '__main__'です。 それ以外の場合は、モジュールをインポートする名前です。

  • したがって、 ifブロックの下のコードは、モジュールがプログラムのエントリポイントであるifにのみ実行されます。

  • インポート時にコードブロックを実行せずに、モジュール内のコードを他のモジュールでインポートできるようにします。

なぜ私たちはこれが必要なのですか?

コードの開発とテスト

あなたがモジュールとして使うように設計されたPythonスクリプトを書いているとしましょう:

def do_important():
    """This function does something very important"""

この関数の呼び出しを一番下に追加することで、モジュールをテストすることができます:

do_important()

コマンドプロンプトで以下のように実行します。

~$ python important.py

問題

ただし、モジュールを別のスクリプトにインポートする場合は、次のようにします。

import important

インポート時には、 do_important関数が呼び出されますので、最下部の関数呼び出しdo_important()コメントアウトしてください。

# do_important() # I must remember to uncomment to execute this!

テスト関数呼び出しをコメントアウトしたかどうかを覚えておく必要があります。 そしてこの複雑さは、あなたが忘れる可能性が高いことを意味し、開発プロセスを面倒にします。

より良い方法

__name__変数は、Pythonインタプリタが現時点で存在する場所であれば、名前空間を指します。

インポートされたモジュール内では、そのモジュールの名前です。

しかし、プライマリモジュール(インタラクティブなPythonセッション、インタプリタのRead、Eval、Print Loop、またはREPL)の内部では、 "__main__"からすべてを実行しています。

したがって、実行する前にチェックすると:

if __name__ == "__main__":
    do_important()

上記のコードでは、コードをプライマリモジュールとして実行しているとき(または別のスクリプトから意図的に呼び出すとき)にのみコードが実行されます。

より良い方法

しかし、これを改善するためのPythonの方法があります。

このビジネスプロセスをモジュールの外部から実行したい場合はどうすればよいですか?

このような関数で開発しテストするときに実行したいコードを置いて、直後に'__main__'チェックします:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()

モジュールを最終モジュールとして実行すると、モジュールの最終機能が実行されます。

main関数を実行せずにモジュールとその関数とクラスを他のスクリプトにインポートすることができます。また、モジュール(とその関数とクラス)を別の'__main__'モジュールから実行するときに呼び出すこともできます。

import important
important.main()

この慣用句は、 __main__モジュールの説明のPythonドキュメントにもあります。 そのテキストの状態:

このモジュールは、インタプリタのメインプログラムが実行する(そうでなければ匿名の)スコープを表します。コマンドは、標準入力、スクリプトファイル、または対話型プロンプトから読み込まれます。 慣用の「条件付きスクリプト」スタンザがスクリプトを実行するのは、この環境です。

if __name__ == '__main__':
    main()



if __name__ == "__main__":if __name__ == "__main__":ますか?

__name__は、すべての名前空間に存在するグローバル変数です(Pythonではglobalは実際にはモジュールレベルを意味します )。 通常、モジュール名( str型)です。

しかし、唯一の特別なケースとして、mycode.pyのように、Pythonのプロセスを実行するにあたって:

python mycode.py

そうでなければ匿名のグローバル名前空間には、その__name__'__main__'値が割り当てられます。

したがって、 最終ラインを含め

if __name__ == '__main__':
    main()
  • mycode.pyスクリプトの終わりに、
  • それがPythonプロセスによって実行されるプライマリのエントリポイントモジュールである場合、

スクリプトの一意に定義されたmain関数が実行されます。

このコンストラクトを使用するもう1つの利点は、コードを別のスクリプトのモジュールとしてインポートしてから、プログラムが次のように決定したときにmain関数を実行することもできます。

import mycode
# ... any amount of other code
mycode.main()



私たちのモジュール( M.py )に、main(インポートされていない)として実行されているときに実行したい特定のステートメントがある場合、それらのステートメント(test-cases、printステートメント)をこのifブロックの下に置くことがifます。

デフォルトでは(モジュールがmainとして実行され、インポートされていない場合)、 __name__変数は"__main__"設定され、インポートされると、 __name__変数は異なる値を__name__ます。おそらくモジュール名( 'M' )。 これは、モジュールの異なるバリアントを一緒に実行し、特定の入出力文を分離し、テストケースがある場合にも役立ちます。

つまり 、モジュールがインポートされたときに(特定の)コードが実行されないようにするには、この ' if __name__ == "main"ブロックを使用します。




簡単に言えば、 __name__は、スクリプトがメインモジュールとして実行されているのか、インポートされたモジュールとして実行されているのかを定義する各スクリプトに対して定義された変数です。

したがって、2つのスクリプトがある場合は、

#script1.py
print "Script 1's name: {}".format(__name__)

そして

#script2.py
import script1
print "Script 2's name: {}".format(__name__)

script1の実行による出力は

Script 1's name: __main__

そして、script2の実行結果は次のようになります。

Script1's name is script1
Script 2's name: __main__

ご覧のように、 __name__はどのコードが「メイン」モジュールであるかを示します。 C / C ++のような構造的な問題を心配する必要はなく、ファイルが 'main'関数を実装していない場合、実行可能ファイルとしてコンパイルできない場合、ライブラリとして使用することはできません。

偉大なことをするPythonスクリプトを記述し、他の目的に役立つたくさんの関数を実装しているとします。 私がそれらを使いたいのであれば、あなたのプログラムを実行することなくあなたのスクリプトをインポートすることができます(あなたのコードはif __name__ == "__main__":コンテキスト内でのみ実行されます)。 一方、C / C ++では、これらの部分を個別のモジュールに分けて、ファイルを組み込む必要があります。 以下の状況を描写する。

矢印はインポートリンクです。 以前のモジュールコードを含む3つのモジュールには、6つのファイル(9つ、実装ファイル数)と5つのリンクがあります。 これは、ライブラリとして特別にコンパイルされていない限り、他のコードをCプロジェクトに組み込むのを困難にします。 今すぐPythonのためにそれを描写してください:

あなたはモジュールを書いています。誰かがあなたのコードを使用したいのであれば、それをインポートするだけで、 __name__変数はプログラムの実行可能部分をライブラリ部分から分離するのに役立ちます。




検討してください:

if __name__ == "__main__":
    main()

Pythonスクリプトの__name__属性が"__main__"であるかどうかをチェックします。 言い換えれば、プログラム自体が実行された場合、属性は__main__になるので、プログラムが実行されます(この場合はmain()関数)。

しかし、Pythonスクリプトがモジュールで使用されているifは、 if文の外側のコードが実行されるため、プログラムがモジュールとして使用されているかどうかをチェックするためにif \__name__ == "\__main__"したがって、コードを実行するかどうかを決定します。




システム(Pythonインタプリタ)がソースファイル(モジュール)用に用意している変数はたくさんあります。 いつでも必要なときに値を取得できるので、__ name__変数/属性に注目しましょう:

Pythonがソースコードファイルを読み込むと、Pythonはそこにあるすべてのコードを実行します。 (ファイルに定義されているすべてのメソッドと関数を呼び出すわけではありませんが、定義しています。)

インタプリタがソースコードファイルを実行する前に、そのファイルにはいくつかの特殊変数が定義されています。 __name__はPythonが各ソースコードファイルに対して自動的に定義する特別な変数の1つです。

Pythonがこのソースコードファイルをメインプログラム(つまり実行しているファイル)としてロードしている場合、このファイルの特別な__name__変数に"__main__"という値を設定します。

これが別のモジュールからインポートされている場合、 __name__はそのモジュールの名前に設定されます。

ですから、あなたの例では、

if __name__ == "__main__":
   lock = thread.allocate_lock()
   thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
   thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

コードブロック:

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

モジュールを直接実行した場合にのみ実行されます。 その特定のインスタンスで__name__の値が " main "に等しくないため、別のモジュールが呼び出し/インポートしている場合、コードブロックは実行されません。

これが助けてくれるといいですね。




これは、Pythonファイルがコマンドラインから呼び出されたときに特別に使用されます。 これは通常、 "main()"関数を呼び出したり、例えばコマンドライン引数のような他の適切な起動コードを実行するために使用されます。

いくつかの方法で書くことができます。 もう一つは:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

私はこれをプロダクションコードで使うべきではありませんがif __name__ == '__main__'は何も "魔法的"ではないことを示しています。 Pythonファイルでmain関数を呼び出すのは良い慣習です。




の理由

if __name__ == "__main__":
    main()

主にコードを直接インポートすることによって発生するインポートロックの問題を回避することです 。 あなたのファイルが直接呼び出された場合(つまり__name__ == "__main__"場合) main()を実行したいの__name__ == "__main__"が、コードがインポートされた場合、インポートロックの問題を避けるためにインポータは本当のメインモジュールからコードを入力する必要があります。

副作用は、複数のエントリポイントをサポートする方法論に自動的にサインオンすることです。 main()をエントリーポイントとして使用してプログラムを実行できますが、必ずしもそうする必要はありませんsetup.pymain()期待していますが、他のツールは別のエントリポイントを使います。 たとえば、ファイルをgunicornプロセスとして実行するには、 main()代わりにapp()関数を定義します。 setup.pyと同じように、 gunicornはあなたのコードをインポートするので、import lockの問題のために、importしている間に何もしたくないのです。




検討してください:

print __name__

上記の出力は__main__

if __name == "__main__":
  print "direct method"

上記のステートメントは真であり、 "直接メソッド"を出力します。 このクラスを他のクラスにインポートした場合、インポート中に__name__ equal to "firstmodel name"設定するため、 "直接メソッド"は表示されません。




この.pyファイルが他の.pyファイルによってインポートされた場合、 "if文"の下のコードは実行されません。

この.pyがシェルの下でpython this_py.pyによって実行されるか、Windowsでダブルクリックされます。 if文の下のコードが実行されます。

これは通常テストのために書かれています。




すべての答えが機能を説明してくれました。しかし、私はそのコンセプトをさらにクリアするのに役立つかもしれないその使用法の一例を提供します。

2つのPythonファイル、a.pyとb.pyがあるとします。今、a.pyはb.pyをインポートします。a.pyファイルを実行します。ここでは、 "import b.py"コードが最初に実行されます。残りのa.pyコードを実行する前に、b.pyファイルのコードを完全に実行する必要があります。

b.pyコードには、そのファイルb.pyに排他的なコードがいくつかあり、b.pyファイルをインポートして実行する他のファイル(b.pyファイル以外)は必要ありません。

これが、このコード行がチェックする内容です。コードが実行されているメインファイル(つまりb.py)(この場合はa.pyが実行中のメインファイルです)では、コードだけが実行されます。




if name == ' main ':

我々は__name__ == '__main__':かなり頻繁に参照してください。

モジュールがインポートされているかどうかをチェックします。

言い換えると、ifブロック内のコードは、コードが直接実行されている場合にのみ実行されます。ここでdirectlyは意味するnot imported

モジュールの名前を出力する簡単なコードを使って何が行われているのか見てみましょう:

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

経由python test.pyで直接コードを実行すると、モジュール名は__main__次のようになります。

call test()
test module name=__main__



Related