__name__ ==「__main__」の場合はどうなりますか?


6065

次のコードが与えられた場合、何をし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__":ブロック条件は、Python 3限り廃止/非推奨とされていますか?私はそれを述べているいくつかの情報を見つけました。
carloswm85

2
@ carloswm85それは真実ではありません。
Giorgos Myrianthous

回答:


6645

Pythonインタープリターがソースファイルを読み取るときは常に、次の2つのことを行います。

  • のようないくつかの特別な変数を設定し、__name__次に

  • ファイル内のすべてのコードを実行します。

これがどのように機能し__name__、Pythonスクリプトで常に確認されるチェックに関する質問にどのように関連するかを見てみましょう。

コードサンプル

少し異なるコードサンプルを使用して、インポートとスクリプトがどのように機能するかを見てみましょう。次のファイルがと呼ばれているとしますfoo.py

# Suppose this is foo.py.

print("before import")
import math

print("before functionA")
def functionA():
    print("Function A")

print("before functionB")
def functionB():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

特殊変数

Python interpeterがソースファイルを読み取るとき、最初にいくつかの特別な変数を定義します。この場合、__name__変数を考慮します。

モジュールがメインプログラムの場合

モジュール(ソースファイル)をメインプログラムとして実行している場合、たとえば

python foo.py

インタプリタはハードコードされた文字列"__main__"__name__変数に割り当てます、すなわち

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

モジュールが別のモジュールによってインポートされたとき

一方、他のモジュールがメインプログラムであり、モジュールをインポートするとします。これは、メインプログラム、またはメインプログラムがインポートする他のモジュールに次のようなステートメントがあることを意味します。

# Suppose this is in some other main program.
import foo

インタープリターはfoo.pyファイルを検索し(他のいくつかのバリアントも検索します)、そのモジュールを実行する前に"foo"、インポートステートメントから__name__変数に名前を割り当てます。

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

モジュールのコードの実行

特殊変数が設定された後、インタープリターはモジュール内のすべてのコードを一度に1つのステートメントで実行します。この説明をたどるには、コードサンプルの横にある別のウィンドウを開いてください。

常に

  1. 文字列を出力します"before import"(引用符なし)。

  2. mathモジュールをロードし、という変数に割り当てますmath。これはimport math、次のものと置き換えることと同じです(これは__import__、文字列を取得して実際のインポートをトリガーするPythonの低レベル関数であることに注意してください)。

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. 文字列を出力します"before functionA"

  2. defブロックを実行して関数オブジェクトを作成し、その関数オブジェクトをと呼ばれる変数に割り当てますfunctionA

  3. 文字列を出力します"before functionB"

  4. 2番目のdefブロックを実行して、別の関数オブジェクトを作成し、それをと呼ばれる変数に割り当てますfunctionB

  5. 文字列を出力します"before __name__ guard"

モジュールがメインプログラムの場合のみ

  1. モジュールがメインプログラムである場合は、それ__name__が実際にに設定されていることがわかり"__main__"、文字列"Function A"とを出力する2つの関数が呼び出されます"Function B 10.0"

モジュールが別のモジュールによってインポートされた場合のみ

  1. 代わりに)モジュールがメインプログラムではなく、別のプログラムによってインポートされた場合__name__"foo"、ではなく"__main__"となり、ifステートメントの本文はスキップされます。

常に

  1. "after __name__ guard"両方の状況で文字列を出力します。

概要

要約すると、2つのケースで出力される内容は次のとおりです。

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

なぜこのように機能するのですか?

なぜ誰もがこれを望んでいるのか疑問に思うかもしれません。まあ、.py他のプログラムやモジュールとしてモジュールとして使用でき、メインプログラム自体としても実行できるファイルを作成したい場合があります。例:

  • モジュールはライブラリですが、いくつかの単体テストやデモを実行するスクリプトモードが必要です。

  • モジュールはメインプログラムとしてのみ使用されますが、ユニットテストがいくつかあります。テストフレームワークは.py、スクリプトなどのファイルをインポートし、特別なテスト関数を実行することで機能します。モジュールをインポートしているからといって、スクリプトの実行を試みたくありません。

  • モジュールは主にメインプログラムとして使用されますが、上級ユーザー向けのプログラマー向けのAPIも提供します。

これらの例を超えて、Pythonでスクリプトを実行することは、いくつかの魔法の変数を設定してスクリプトをインポートするだけであるのはエレガントです。スクリプトの「実行」は、スクリプトのモジュールをインポートすることの副作用です。

思考の糧

  • 質問:__name__チェックブロックを複数持つことはできますか?回答:そうするのは奇妙ですが、言語はあなたを止めません。

  • 次のものがにあるとしますfoo2.pypython foo2.pyコマンドラインで言うとどうなりますか?どうして?

# Suppose this is foo2.py.

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
  • ここで、__name__チェックインを削除するとどうなるかを考えますfoo3.py
# Suppose this is foo3.py.

def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
print("m1")
functionA()
print("m2")
print("t2")
  • スクリプトとして使用するとどうなりますか?モジュールとしてインポートした場合?
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")

print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")

14
好奇心から:subprocess.run('foo_bar.py')Pythonスクリプトで実行するとどうなりますか?cmdを手動で入力したときfoo_bar__name__ = '__main__'同じように開始されると思いますfoo_bar.py。それは事実ですか?@MrFooz 'Answerを考慮に入れると、これを実行して、一度に多くの「メイン」モジュールを好きなだけ持つことに問題はありません。__name__値を変更したり、複数のインスタンスを個別に作成したり(またはによってsubprocess相互に作成したインスタンス)が相互に作用したりする場合でも、Pythonの通常のビジネスです。私は何かを逃していますか?
hajef

12
@hajefあなたは物事がどのように機能するかについて正しいですsubprocess.run。とはいえ、スクリプト間でコードを共有する一般的なより良い方法は、モジュールを作成し、スクリプトがお互いをスクリプトとして呼び出す代わりに共有モジュールを呼び出すようにすることです。これは、デバッグするのは難しいsubprocess.runなど、ほとんどのデバッガは、プロセス境界を越えてジャンプしていないので、それは余分なプロセスを作成し、破壊するために非自明なシステムのオーバーヘッドを追加することができます呼び出し
氏Fooz

4
Food for thinkセクションのfoo2.pyの例に疑問があります。私の見解では、foo2.pyをfunctionBからインポートするだけです
user471651

1
@MrFooz私はこのxDのようなことをするつもりはまったくありませんでした。この種のものに彼らの心を包み込みます。@ user471651 from foo2 import functionBfoo2をfunctionBからインポートする必要があるのはなぜですか?それは意味のゆがみです。from module import methodモジュールからメソッドをインポートします。
hajef

2
コードをインポートできるモジュールの1つは、multiprocessing特にWindowsでこのテストを必要とするモジュールです。
Yann Vernier

1801

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

python myscript.py

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

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

if __name__ == "__main__":
    ...

スクリプトが別のモジュールにインポートされている場合、そのさまざまな関数とクラスの定義がインポートされ、そのトップレベルのコードが実行されますが、if上記の節のthen-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__等しくなり"one"ます"__main__"


素晴らしい答えです。これは私の意見では最も明確な答えでした。+1!
TheTechRobo36414519

その考え方についての+1:最初のインデントされた行は、最初の行で関数を実行するまで、最初にのみ実行されます
Elijah Mock

719

__name__変数(imho)の最も簡単な説明は次のとおりです。

以下のファイルを作成します。

# a.py
import b

そして

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

それらを実行すると、次の出力が得られます。

$ python a.py
Hello World from b!

ご覧のように、モジュールがインポートされると、Pythonはglobals()['__name__']このモジュールにモジュールの名前を設定します。また、インポート時にモジュール内のすべてのコードが実行されます。以下のようifに声明を評価しFalse、この部分は実行されません。

$ python b.py
Hello World from __main__!
Hello World again from __main__!

ご覧のとおり、ファイルが実行されると、Pythonはglobals()['__name__']このファイルをに設定します"__main__"。今回は、ifステートメントが評価されTrue、実行されています。


513

何をしif __name__ == "__main__":ますか?

基本を概説するには:

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

  • したがって、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()

このイディオムは、Pythonドキュメントの__main__モジュールの説明にもあります。そのテキストは述べています:

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

if __name__ == '__main__':
    main()

125

if __name__ == "__main__"は、スクリプトが(たとえば)コマンドラインからのようなコマンドを使用して実行されるときに実行される部分ですpython myscript.py


2
なぜファイルないhelloworld.pyだけでprint("hello world")、その中には、コマンドで実行することはできませんpython helloworld.py何があってもif __name__ == "__main__"
hi15、19年

83

何をしif __name__ == "__main__":ますか?

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

ただし、唯一の特殊なケースとして、mycode.pyのように、実行するPythonプロセスでは次のようになります。

python mycode.py

そうでない場合は、匿名のグローバル名前空間には、の値が割り当てられている'__main__'そのにし__name__

したがって、最終行を含める

if __name__ == '__main__':
    main()
  • mycode.pyスクリプトの最後に、
  • Pythonプロセスによって実行される主要なエントリポイントモジュールの場合

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

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

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

72

ここでは、問題のコードのしくみである「方法」についてさまざまな見方がたくさんありますが、「なぜ」を理解するまでは、どれも意味がありませんでした。これは、新しいプログラマーにとって特に役立つはずです。

ファイル「ab.py」を取得します。

def a():
    print('A function in ab file');
a()

そして、2番目のファイル "xy.py":

import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()

このコードは実際に何をしていますか?

実行するとxy.py、あなたimport ab。importステートメントはインポート時にモジュールをすぐにab実行するため、の操作はの残りのxyの前に実行されます。で終了するとab、に進みxyます。

インタープリターは、で実行されているスクリプトを追跡し__name__ます。スクリプトを実行すると、名前に関係なく、インタープリターが"__main__"スクリプトを呼び出し、外部スクリプトの実行後に返されるマスターまたは「ホーム」スクリプトにします。

この"__main__"スクリプトから呼び出される他のスクリプトには、そのファイル名が割り当てられます__name__(例:)__name__ == "ab.py"。したがって、この行if __name__ == "__main__":は、最初に実行された「ホーム」スクリプトを解釈/解析しているかどうか、または一時的に別の(外部)スクリプトを調べているかどうかを判断するインタープリターのテストです。これにより、プログラマーは、スクリプトを直接実行する場合と外部から呼び出す場合とでスクリプトの動作が異なるように柔軟に設定できます。

上記のコードをステップ実行して、何が起こっているのかを理解します。まず、インデントされていない行とスクリプトに表示される順序に注目します。関数-またはdef-ブロックは、呼び出されるまでそれ自体では何も実行しないことに注意してください。自分自身につぶやいた場合の通訳の発言:

  • 'home'ファイルとしてxy.pyを開きます。それを呼ん"__main__"__name__変数。
  • でファイルをインポートして開きます__name__ == "ab.py"
  • ああ、機能。覚えておきます。
  • わかりました、関数a(); 私はちょうどそれを学びました。印刷 ' abファイル内関数 '。
  • ファイルの終わり。に戻る"__main__"
  • ああ、機能。覚えておきます。
  • 別のもの。
  • 機能x(); わかりました、「周辺タスク:他のプロジェクトで役立つかもしれません」を出力します。
  • これは何ですか?if声明。さて、条件が満たされている(変数__name__がに設定されている"__main__")ので、main()関数を入力して' main関数を出力します。これがアクションの場所です '。

下の2行は、「これが"__main__"「ホーム」スクリプトの場合、呼び出される関数を実行する」という意味ですmain()。そのためdef main():、スクリプトの機能のメインフローを含むブロックが上部に表示されます。

なぜこれを実装するのですか?

以前にインポートステートメントについて言ったことを覚えていますか?モジュールをインポートするとき、それは単にそれを「認識する」だけでなく、さらなる指示を待つのではなく、実際にはスクリプト内に含まれるすべての実行可能な操作を実行します。そのため、スクリプトの主要部分をmain()関数に入れると、効果的に隔離され、別のスクリプトによってインポートされたときにすぐに実行されないように隔離されます。

繰り返しになりますが、例外はありますが、main()通常、外部から呼び出されることはありません。では、もう1つ疑問に思っているかもしれません。「」を呼び出さない場合main()、なぜスクリプトを呼び出すのでしょうか。これは、多くの人々がファイル内の残りのコードとは独立して実行されるように構築されたスタンドアロン関数でスクリプトを構成しているためです。その後、スクリプトの本文の別の場所で呼び出されます。これは私にこれをもたらします:

しかし、コードはそれなしで動作します

はい、そうです。これらの個別の関数main()関数内に含まれていないインラインスクリプトから呼び出すことできます。あなたが(私がそうであるように、プログラミングの初期の学習段階で)必要なことを正確に実行するインラインスクリプトを作成することに慣れている場合、その操作が再び必要になった場合は、もう一度それを理解しようとします。 。まあ、コードのこのような内部構造には慣れていません。なぜなら、ビルドするのがより複雑であり、読むのも直感的ではないからです。

しかし、それはおそらく外部から呼び出される関数を持つことができないスクリプトです。そうすると、すぐに変数の計算と割り当てを開始するからです。また、関数を再利用しようとしている場合、新しいスクリプトは古いスクリプトと十分に関連しているため、変数の競合が発生する可能性があります。

独立した関数を分割することで、以前の作業を別のスクリプトに呼び出して再利用できるようになります。たとえば、「example.py」は「xy.py」をインポートしてを呼び出しx()、「xy.py」の「x」関数を利用します。(多分それは与えられたテキスト文字列の3番目の単語を大文字にしている;数値のリストからNumPy配列を作成してそれらを二乗する;または3Dサーフェスのトレンドを取り除く。可能性は無限である。)

(余談ですが、この質問には、@ kindallによる回答が含まれており、最終的には理解するのに役立ちました。理由は、方法ではありません。残念ながら、この質問の複製としてマークされています。これは間違いだと思います。)


52

モジュール(M.py)がメイン(インポートされていない)として実行されるときに実行される特定のステートメントがある場合、それらのステートメント(テストケース、印刷ステートメント)をこのifブロックの下に配置できます。

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

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


43

簡単に言うと、__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 ++のような構造上の問題を心配する必要がないためです。この場合、ファイルが「メイン」関数を実装していない場合、実行可能ファイルとしてコンパイルできません。その後、ライブラリとして使用することはできません。

あなたが何か素晴らしいことをするPythonスクリプトを書き、他の目的に役立つ関数のボートロードを実装するとします。それらを使用したい場合は、スクリプトをインポートして、プログラムを実行せずに使用できます(コードがif __name__ == "__main__":コンテキスト内でのみ実行される 場合)。一方、C / C ++では、これらの部分を別のモジュールに分割して、ファイルを含める必要があります。以下の状況を想像してください。

Cでの複雑なインポート

矢印はインポートリンクです。3つのモジュールがそれぞれ前のモジュールコードをインクルードしようとしている場合、6つのファイル(9つは実装ファイルを数えます)と5つのリンクがあります。これにより、ライブラリとして具体的にコンパイルされない限り、他のコードをCプロジェクトに組み込むことが難しくなります。今それをPythonのために描きます:

Pythonでのエレガントなインポート

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


2
C / C ++の図は間違っています:同じユニット名の3倍(file1)。
ウルフ

40

より抽象的な方法で答えを見てみましょう:

次のコードがあるとしx.pyます。

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

ブロックAとBは、実行中に実行されx.pyます。

しかしy.py、たとえば、x.pyインポートされ、そこからコードが実行される別のモジュールを実行しているとき(Bでなく)ブロックAだけが実行されます(関数x.pyがから呼び出されるときなどy.py)。


1
投稿を編集できませんでした(変更が必要な場合は最低6文字)。行14には、「x.py」ではなく「xy」があります。
alwaysLearning

35

Pythonをインタラクティブに実行すると、ローカル__name__変数に値が割り当てられます__main__。同様に、Pythonモジュールを別のモジュールにインポートするのではなく、コマンドラインから実行すると、その__name__属性には__main__、モジュールの実際の名前ではなくの値が割り当てられます。このようにして、モジュールは独自の__name__値を確認して、別のプログラムのサポートとして、またはコマンドラインから実行されるメインアプリケーションとして、それらがどのように使用されているかを自分で判断できます。したがって、次のイディオムはPythonモジュールでは非常に一般的です。

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.

34

検討してください:

if __name__ == "__main__":
    main()

__name__Pythonスクリプトの属性がかどうかをチェックします"__main__"。つまり、プログラム自体が実行される場合、属性はになる__main__ため、プログラムが実行されます(この場合、main()関数)ます。

ただし、Pythonスクリプトがモジュールで使用されている場合、ifステートメント外のコードが実行されるためif \__name__ == "\__main__"、プログラムがモジュールとして使用されているかどうかを確認するためにのみ使用され、コードを実行するかどうかを決定します。


明るい答えを書くには時間がかかり過ぎているようです+1
snr

27

何かについて説明する前に、if __name__ == '__main__'それが何で何をするのかを理解することが重要__name__です。

なに__name__

__name__あるDunderAlias(モジュールからアクセス可能)グローバル変数として考えることができるとと同様に作品-global

これは、次のように文字列(上記のようにグローバル)です。 type(__name__)(yielding <class 'str'>)で)であり、Python 3Python 2の両方のバージョンの組み込み標準です。

どこ:

スクリプトで使用できるだけでなく、インタープリターとモジュール/パッケージの両方で使用することもできます。

通訳:

>>> print(__name__)
__main__
>>>

脚本:

test_file.py

print(__name__)

その結果 __main__

モジュールまたはパッケージ:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

その結果 somefile

パッケージまたはモジュールで使用される場合__name__、ファイルの名前を取ることに注意してください。実際のモジュールまたはパッケージのパスは指定されていませんが、独自のDunderAliasがあります__file__が、これを可能にするがあります。

__name__メインファイル(またはプログラム)がどこにあるかが常に返され__main__、それがモジュール/パッケージ、または他のPythonスクリプトで実行されているものである場合は、ファイルの名前が返されることがわかります。由来しています。

練習:

変数であることは、その値上書きできることを意味し(「できる」とは「すべき」という意味ではありません)、__name__と、読みにくくなります。したがって、何らかの理由でそれを行わないでください。変数が必要な場合は、新しい変数を定義します。

の値は常に __name__to__main__またはファイルの名前であるます。もう一度このデフォルト値を変更すると、うまくいくという混乱が生じ、将来的に問題が発生します。

例:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

一般的には、 if __name__ == '__main__'スクリプトに。

今答える if __name__ == '__main__'

今私たちはの行動を知っています __name__物事より明確になることがわかりました。

if指定された値がtrueの場合に実行するコードのブロックが含まれているフロー制御ステートメントです。私たちは__name__どちらかを取ることができることを 見てきました__main__または、インポート元のファイル名をことを確認しました。

これは、 __name__がと等しい__main__、ファイルはメインファイルであり、スクリプトにインポートされたモジュールやパッケージではなく、実際に実行されている(またはインタープリターである)必要があります。

確かに __name__にの値を取る__main__、そのコードブロック内にあるものは何でも実行されます。

これは、実行中のファイルがメインファイルの場合(またはインタープリターから直接実行している場合)、その条件が実行される必要があることを示しています。それがパッケージである場合、それはすべきではなく、値はになります__main__

モジュール:

__name__ モジュールの名前を定義するためにモジュールで使用することもできます

バリエーション:

他にも、あまり一般的ではないが便利なことを__name__で行うこともできます。その一部をここに示します。

ファイルがモジュールまたはパッケージの場合のみ実行:

if __name__ != '__main__':
    # Do some useful things 

ファイルがメインの場合は1つの条件を実行し、そうでない場合は別の条件を実行します。

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

また、ライブラリを複雑に使用せずに、パッケージとモジュールに実行可能なヘルプ機能/ユーティリティを提供するために使用することもできます。

また、コマンドラインからメインスクリプトとしてモジュールを実行できるため、非常に便利です。


25

私は答えを詳細かつ簡単な言葉で解読するのが最善だと思います:

__name__:Pythonのすべてのモジュールには、 __name__。これは、モジュールの名前を返す組み込み変数です。

__main__:他のプログラミング言語と同様に、Pythonにも実行エントリポイント、つまりmainがあります。'__main__' トップレベルのコードが実行されるスコープの名前です。基本的に、Pythonモジュールを使用する方法は2つあります。スクリプトとして直接実行するか、インポートします。モジュールをスクリプトとして実行すると、そのモジュールはに__name__設定され__main__ます。

したがって、__name__属性の値は、__main__モジュールがメインプログラムとして実行されるときに設定されます。そうでない場合、の値は__name__ モジュールの名前を含むように設定されます。


23

これは、Pythonファイルがコマンドラインから呼び出される場合の特別なものです。これは通常、「main()」関数の呼び出しや、たとえばコマンドライン引数の処理など、他の適切な起動コードの実行に使用されます。

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

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

これを製品コードで使用するべきだと言っているわけではありませんが、これには「魔法」が何もないことを示すのに役立ちますif __name__ == '__main__'。これは、Pythonファイルでmain関数を呼び出すのに適した規則です。


7
あなたが1)副作用に依存していて2)乱用しているので、私はこの悪い形を考えますandand2つのブールステートメントが両方とも真であるかどうかをチェックするために使用されます。の結果には興味がないのでandifステートメントは意図をより明確に伝えます。
jpmc26 2013

8
ブール演算子の短絡動作をフロー制御メカニズムとして利用することが悪いスタイルであるかどうかという問題は別として、より大きな問題は、これ問題にまったく答えないことです。
マークアメリー2015

@MarkAmeryハハ、シーシュ、今はそうです。😊
教授ファルケン契約が破ら

19

システム(Pythonインタープリター)がソースファイル(モジュール)に提供する変数は多数あります。いつでも好きなときに値を取得できるので、__ name__に注目しましょう変数/属性に。

Pythonがソースコードファイルをロードすると、その中にあるすべてのコードが実行されます。(ファイルで定義されているすべてのメソッドと関数を呼び出すのではなく、それらを定義することに注意してください。)

ただし、インタープリターはソースコードファイルを実行する前に、そのファイルのいくつかの特別な変数を定義します。__名前__は、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に等しくないため、別のモジュールがそれを呼び出し/インポートしている場合、コードブロックは実行されません。その特定のインスタンスの」に。

これがお役に立てば幸いです。


17

if __name__ == "__main__": 基本的にはトップレベルのスクリプト環境であり、インタープリターを指定します(「最初に実行するのが最も優先されます」)。

'__main__'トップレベルのコードが実行されるスコープの名前です。モジュールの__name__'__main__'、標準入力、スクリプト、または対話型プロンプトから読み取った場合と同じに設定されます。

if __name__ == "__main__":
    # Execute only if run as a script
    main()

17

私は、このページの回答を通して、たくさん読んでいます。私は、あなたがそのことを知っていれば、確かにそれらの答えを理解するでしょう、そうでなければ、あなたはまだ混乱しています。

簡単に言うと、いくつかの点を知っておく必要があります。

  1. import a アクションは実際に「a」で実行できるすべてのものを実行します

  2. ポイント1のため、インポート時にすべてを「a」で実行したくない場合があります

  3. ポイント2の問題を解決するために、Pythonでは条件チェックを行うことができます

  4. __name__すべての.pyモジュールで暗黙的な変数です。ときa.pyにインポートされ、値__name__a.pyモジュールは、そのファイル名」に設定されていますa「。場合は、a.py直接「使用して実行されpython a.pyている意味し、」a.pyエントリポイントで、その後の値__name__a.pyモジュールがストリングに設定されています__main__

  5. Python __name__が各モジュールの変数を設定するメカニズムに基づいて、ポイント3を達成する方法を知っていますか?答えは簡単ですよね?if条件を入れます:if __name__ == "__main__": ...; __name__ == "a"機能的な必要性に応じて、置くこともできます

Pythonの特別な点はポイント4です!残りは単なる基本的なロジックです。


1
はい、ポイント1は理解することが不可欠です。それから、このメカニズムの必要性が明らかになります。
ユーレカ

16

検討してください:

print __name__

上記の出力は__main__です。

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

上記のステートメントはtrueであり、「直接メソッド」を出力します。このクラスを別のクラスにインポートした場合、インポート中にが設定されるため、「ダイレクトメソッド」を出力しないとします__name__ equal to "first model name"


14

このファイルをスクリプトとして、またインポート可能なモジュールとして使用できるようにすることができます

fibo.py(という名前のモジュールfibo

# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

リファレンス:https : //docs.python.org/3.5/tutorial/modules.html


14

の理由

if __name__ == "__main__":
    main()

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

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


3
インポートロックについて学ぶのは良いことです。[...]もう少し別の方法論へのサインオンについて説明していただけませんか?
ウルフ

1
@ウルフ:はい。複数のエントリポイントの方法論に関するいくつかの文を追加しました。
personal_cloud

11

この答えは、Pythonを学ぶJavaプログラマー向けです。通常、すべてのJavaファイルには1つのパブリッククラスが含まれています。このクラスは次の2つの方法で使用できます。

  1. 他のファイルからクラスを呼び出します。呼び出し元のプログラムにインポートするだけです。

  2. テスト目的で、クラスをスタンドアロンで実行します。

後者の場合、クラスにはpublic static void main()メソッドが含まれている必要があります。Pythonでは、この目的はグローバルに定義されたラベルによって提供され'__main__'ます。


11

下のコードif __name__ == '__main__': は、モジュールがスクリプトとして呼び出された場合にのみ実行されます

例として、次のモジュールを考えますmy_test_module.py

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

1番目の可能性:my_test_module.py別のモジュールでのインポート

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

今、あなたが呼び出す場合main.py

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

のトップレベルのprint()ステートメントのみmy_test_moduleが実行されることに注意してください。


2番目の可能性:my_test_module.pyスクリプトとして呼び出す

my_test_module.pyPythonスクリプトとして実行すると、両方のprint()ステートメントが実行されます。

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

10

Pythonのすべてのモジュールには、という属性があります__name____name__ 属性 の値は__main__ 、のようにモジュールが直接実行されるときですpython my_module.py。それ以外の場合(と言うようにimport my_module)の値は__name__ モジュールの名前です。

簡単に説明する小さな例。

#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

これを次のように直接実行できます

python test.py  

出力

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

今、他のスクリプトから上記のスクリプトを呼び出すと仮定します

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

これを実行すると

python external_calling.py

出力

42
I am inside hello_world
test

したがって、上記は、他のスクリプトからtestを呼び出した場合、ループ__name__インtest.pyが実行されないことを示しています。


6

この.pyファイルが他の.pyファイルによってインポートされる場合、「ifステートメント」の下のコードは実行されません。

この.pyがpython this_py.pyシェルの下で実行されている場合、またはWindowsでダブルクリックされている場合。「ifステートメント」の下のコードが実行されます。

通常、テスト用に作成されます。


6

Pythonインタープリターが特定のモジュールを実行している場合、__name__グローバル変数は値を持ちます"__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

このスクリプトを実行すると、プリントが表示されます

a

このファイルをインポートし、ファイルBにAと言ってファイルBを実行すると、if __name__ == "__main__"ファイルAがfalseになるため、印刷され ます。

b


5

すべての答えは機能性をほとんど説明しました。しかし、私はその使用法の1つの例を提供します。これは、概念をさらに明確にするのに役立つ可能性があります。

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

b.pyコードには、そのファイルb.py専用のコードがいくつかあり、b.pyファイルをインポートした他のファイル(b.pyファイル以外)を実行したくありません。

これが、このコード行がチェックすることです。コードを実行しているメインファイル(つまり、b.py)である場合(この場合はそうではありません(a.pyが実行しているメインファイル))、コードのみが実行されます。


4

ファイルa.pyを作成します。

print(__name__) # It will print out __main__

__name__これは、__main__そのファイルが直接実行され、これがメインファイルであることを示すときは常に等しくなります。

同じディレクトリに別のファイルb.pyを作成します。

import a  # Prints a

それを実行します。それが印刷されます、すなわち、ファイルの名前インポートさを

したがって、同じファイルの2つの異なる動作を示すために、これは一般的に使用されるトリックです。

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly

4

もし名前 ==「メイン」:

場合我々は見__name__ == '__main__':かなり頻繁に。

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

つまり、ifブロック内のコードは、コードが直接実行されたときにのみ実行されます。ここdirectlynot 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__

4

単に、Cプログラミング言語のmain関数のように、ファイルを実行するためのエントリポイントです。


8
この答えは、OP(または同様の質問を持つユーザー)がCに 精通していて、エントリーポイントが何であるか知っている仮定しています。
延期

1
この回答は、if __name__ == "__main__"ブロックの前にコード(副作用のない定義を除く)が発生しないことも前提としています。技術的には、実行されるスクリプトの先頭がプログラムのエントリポイントです。
チャーリーハーディング
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.