__name__ ==“ __main __”の場合はどうなりますか?

6454
Devoted 2009-01-07 18:11.

次のコードを考えると、何をし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))

30 answers

7128
Mr Fooz 2009-01-07 18:26.

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インタープリターがソースファイルを読み取るとき、最初にいくつかの特別な変数を定義します。この場合、__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__"、2つの関数を呼び出して、文字列"Function A"とを出力し"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.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

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.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

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")
1884
Adam Rosenfield 2009-01-07 18:28.

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

python myscript.py

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

この場合、最上位のコードはifブロックです。__name__現在のモジュールの名前に評価される組み込み変数です。ただし、モジュールが(myscript.py上記のように)直接実行されている場合は、__name__代わりに文字列に設定されます"__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__"

745
pi. 2009-01-08 01:35.

__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、実行されています。

522
Aaron Hall 2013-11-23 18:38.

何をし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()

このイディオムは、__main__モジュールの説明のPythonドキュメントにも記載されています。そのテキストは次のように述べています。

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

if __name__ == '__main__':
    main()
130
Harley Holcombe 2009-01-07 18:14.

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

84
Aaron Hall 2014-10-15 10:22.

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

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

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

python mycode.py

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

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

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

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

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

import mycode
# ... any amount of other code
mycode.main()
73
joechoj 2016-09-29 18:33.

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

ファイル「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'の前に実行されます。で終了するとabxy。で続行されます。

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

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

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

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

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

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

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

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

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

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

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

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

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

53
Nabeel Ahmed 2013-04-04 04:09.

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

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

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

46
redbandit 2016-10-15 23:07.

簡単に言うと、__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 ++では、これらの部分を別のモジュールに分割して、ファイルを含める必要があります。以下の状況を想像してください。

矢印はインポートリンクです。それぞれが前のモジュールコードを含めようとしている3つのモジュールには、6つのファイル(9つ、実装ファイルを数える)と5つのリンクがあります。これにより、特にライブラリとしてコンパイルされない限り、他のコードをCプロジェクトに含めることが困難になります。Python用に想像してみてください。

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

42
Alisa 2015-01-21 07:48.

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

このコードが次の場所にあるとしますx.py

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

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

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

36
Zain 2013-12-12 01:23.

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
Larry 2017-08-23 08:53.

考えてみましょう:

if __name__ == "__main__":
    main()

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

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

29
Simon 2018-04-04 09:32.

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

__name__ですか?

__name__はDunderAliasです-グローバル変数(モジュールからアクセス可能)と考えることができ、と同様に機能しglobalます。

それによって示されるように(上述のようにグローバル)文字列であるtype(__name__)(得<class 'str'>)、そして両方のための作り付けの標準ではPython 3およびPythonの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__は、ファイルの名前を使用することに注意してください。実際のモジュールまたはパッケージパスのパスは指定されていません__file__が、これを可能にする独自のDunderAliasがあります。

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

練習:

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

常にの値が想定される__name__こと__main__や、ファイルの名前。もう一度このデフォルト値を変更すると、うまくいくという混乱がさらに生じ、さらに問題が発生します。

例:

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

一般にif __name__ == '__main__'、スクリプトにを含めることをお勧めします。

今答えるためにif __name__ == '__main__'

これで、__name__物事の振る舞いがより明確になることがわかりました。

Anifは、指定された値が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

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

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

27
Inconnu 2016-11-30 20:47.

答えを深く簡単な言葉で打ち破るのが最善だと思います。

__name__:Pythonのすべてのモジュールには、と呼ばれる特別な属性があります__name__。これは、モジュールの名前を返す組み込み変数です。

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

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

27
jack 2018-06-25 05:48.

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

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

  1. import aアクションは実際に実行可能なすべてを実行しますa.py。つまり、の各行はa.py

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

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

  4. __name__すべての.pyモジュールの暗黙変数です。

  • ときa.pyされるimport編、の値__name__a.pyモジュールは、そのファイル名「に設定されていますa
  • a.pyが「python a.py」を使用して直接実行される場合、の値は__name__文字列に設定されます__main__
  1. Python__name__が各モジュールの変数を設定するメカニズムに基づいて、ポイント3を達成する方法を知っていますか?答えはかなり簡単ですよね?if条件を設定します。if __name__ == "__main__": // do A
  • その後python a.py、パーツを実行します// do A
  • そしてimport a部分をスキップします// do A
  1. __name__ == "a"機能的なニーズに応じて置くこともできますが、めったに行いません

Pythonが特別である重要なことは、ポイント4です!残りは基本的なロジックです。

24
Prof. Falken 2013-01-25 03:48.

これは、Pythonファイルがコマンドラインから呼び出される場合に特別です。これは通常、「main()」関数を呼び出すため、またはコマンドライン引数処理などの他の適切なスタートアップコードを実行するために使用されます。

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

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

これを本番コードで使用する必要があると言っているわけではありませんが、について「魔法」は何もないことを説明するのに役立ちますif __name__ == '__main__'。これは、Pythonファイルでmain関数を呼び出すための良い規則です。

20
codewizard 2015-11-26 02:26.

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

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

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

Pythonがこのソースコードファイルをメインプログラム(つまり、実行するファイル)としてロードしている場合、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」と等しくないため、別のモジュールがコードブロックを呼び出し/インポートしている場合、コードブロックは実行されません。

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

19
The Gr8 Adakron 2016-04-24 22:23.

if __name__ == "__main__": は基本的に最上位のスクリプト環境であり、インタプリタを指定します(「最初に実行する優先度が最も高い」)。

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

if __name__ == "__main__":
    # Execute only if run as a script
    main()
16
kgf3JfUtW 2017-03-14 11:44.

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

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

16
Janarthanan Ramu 2016-06-23 00:47.

考えてみましょう:

print __name__

上記の出力は__main__です。

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

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

15
personal_cloud 2017-09-23 08:32.

の理由

if __name__ == "__main__":
    main()

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

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

15
Giorgos Myrianthous 2020-02-02 03:26.

下のコード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.py、Pythonスクリプトとして実行すると、両方の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'
11
Rishi Bansal 2019-06-12 23:28.

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が実行されないことを自明です。

10
Raja 2018-10-07 18:52.

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

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

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

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

6
pah8J 2018-06-20 01:44.

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

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

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

5
Nikil Munireddy 2019-07-31 06:22.

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

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

b

4
Ali Hallaji 2018-04-05 04:32.

名前の場合== 'メイン':

場合我々は見__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__
4
preetika mondal 2018-05-04 22:25.

すべての答えは、機能をほぼ説明しています。しかし、概念をさらに明確にするのに役立つかもしれないその使用法の一例を提供します。

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

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

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

3
DARK_C0D3R 2018-01-09 05:24.

ファイル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
3
PythonMaster202 2020-04-28 02:12.

Pythonのすべてのモジュールには、nameと呼ばれる特別な属性があります。モジュールがメインプログラムとして実行されるとき(実行中など)、name属性の値は「main」に設定されpython foo.pyます。それ以外の場合、nameの値は、呼び出し元のモジュールの名前に設定されます。

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

アトランタのドナ・ブラジル:「私があなたに私の話をするとき私を踏まないでください」

アトランタのドナ・ブラジル:「私があなたに私の話をするとき私を踏まないでください」

2017年11月19日にアトランタで開催されたドナブラジルとモーアイボリー(ダグスミスフォトグラフィー)ドナブラジルを見逃すことはありません。

彼らは北朝鮮から脱出した亡命者の胃の中に奇妙な寄生虫を見つけました

彼らは北朝鮮から脱出した亡命者の胃の中に奇妙な寄生虫を見つけました

画像:ゲッティ陰謀愛好家は新しくてエキサイティングなディスカッション資料を持っています:国境を越えて韓国に5発撃たれた北朝鮮の脱北者は寄生虫でいっぱいで、そのうちの1人は南のメディアは、寄生虫を持った北朝鮮の脱北者を見つけることは珍しいことではないと報告している、実際、男性が30以上のタイプを持っていたケースがあった。

パニッシャーの第2話は、複雑な陰謀の網を織り交ぜています

パニッシャーの第2話は、複雑な陰謀の網を織り交ぜています

写真:パニッシャー(Netflix)これらのMarvel Netflixが愛していることが1つあるとすれば、それは複雑な政府や企業の陰謀です。そして、なぜこれらのショーがそのルートを選択するのかを理解するのは簡単です。

最新のBoseヘッドフォンは音楽を聴くためのものではなく、パートナーの鼻を鳴らすためのものです。

最新のBoseヘッドフォンは音楽を聴くためのものではなく、パートナーの鼻を鳴らすためのものです。

あなたのパートナーはチェーンソーのように詮索し、あなたを眠らせませんか?あなたのパートナーはあなたがチェーンソーのように詮索したと主張しますが、あなたが詮索しないので彼らは彼の想像ですか?あなたのケースが何であれ、Bose(はい、ハイエンドオーディオ機器のメーカー)はあなたのために何かを持っています。それらはBoseSleepbudsと呼ばれます。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language