__name__ ==“ __ main __&#8221 ;:どうしますか?
-
03-07-2019 - |
質問
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))
解決
Pythonインタープリターがソースファイルを読み取るたびに、次の2つのことを行います。
-
__ name __
などのいくつかの特別な変数を設定してから、 -
ファイルで見つかったすべてのコードを実行します。
これがどのように機能し、Pythonスクリプトで常に表示される __ name __
チェックに関する質問とどのように関連するかを見てみましょう。
コードサンプル
インポートとスクリプトがどのように機能するかを調べるために、少し異なるコードサンプルを使用してみましょう。以下が 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
を見て、 .py
を取り除き、その文字列をモジュールの< code> __ 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ステートメントずつ実行します。コードの説明の横にある別のウィンドウを開いて、この説明に従ってください。
常に
-
インポート前の文字列
&quot;&quot;
(引用符なし)を出力します。 -
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")
-
文字列
&quot; functionA&quot;
の前に印刷されます。 -
def
ブロックを実行して関数オブジェクトを作成し、その関数オブジェクトをfunctionA
という変数に割り当てます。 -
文字列
&quot;&functionB&quot;
を出力します。 -
2番目の
def
ブロックを実行して、別の関数オブジェクトを作成し、それをfunctionB
という変数に割り当てます。 -
文字列
&quot;を__name__ guard&quot;
の前に出力します。
モジュールがメインプログラムである場合のみ
- モジュールがメインプログラムの場合、
__ name __
が実際に&quot; __ main __&quot;
に設定されていることがわかり、2つの関数を呼び出して、文字列を出力します< code>&quot;関数A&quot; および&quot;関数B 10.0&quot;
。
モジュールが別のモジュールによってインポートされた場合のみ
- (代わりに)モジュールがメインプログラムではなく、別のモジュールによってインポートされた場合、
__ name __
は&quot; foo&quot;
になります&quot; __ main __&quot;
ではなく、if
ステートメントの本文をスキップします。
常に
- 両方の状況で、文字列
&quot; __ name__ guard&quot;
の後に印刷されます。
概要
要約すると、次の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
なぜこのように機能するのですか?
他のヒント
スクリプトをPythonインタープリターにコマンドとして渡して実行する場合、
python myscript.py
インデントレベル0のすべてのコードが実行されます。定義されている関数とクラスは定義されていますが、それらのコードは実行されません。他の言語とは異なり、自動的に実行される main()
関数はありません- main()
関数は暗黙的にトップレベルのすべてのコードです。
この場合、最上位コードは if
ブロックです。 __ name __
は、現在のモジュールの名前を評価する組み込み変数です。ただし、モジュールを直接実行している場合(上記の myscript.py
の場合)、代わりに __ name __
は文字列&quot; __ main __&quot;
。したがって、テストすることで、スクリプトが直接実行されているか、他の何かによってインポートされているかをテストできます
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 __
は&quot; __ main __&quot; ではなく、
。&quot; one&quot;
と等しくなります
__ name __
変数(imho)の最も簡単な説明は次のとおりです。
次のファイルを作成します。
# a.py
import b
and
# 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 __']
を&quot; __ main __&quot;
に設定します。今回は、 if
ステートメントが True
と評価され、実行されています。
if __name__ ==&quot; __ main __&quot;:
は何をしますか?
基本の概要:
-
プログラムへのエントリポイントであるモジュール内のグローバル変数
__ 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セッション、つまりインタープリターの読み取り、評価、印刷ループ、REPL)内では、&quot; __ main __&quot;
からすべてを実行しています。
したがって、実行する前に確認する場合:
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 __
モジュール。そのテキストの状態:
このモジュールは(それ以外の場合は匿名の)スコープを表します。 インタープリターのメインプログラムが&#8212;を実行しますどちらかから読み取られるコマンド 標準入力、スクリプトファイル、または対話型プロンプトから。それ この環境では、慣用的な&#8220;条件付きスクリプト&#8221;スタンザ スクリプトを実行させます:
if __name__ == '__main__': main()
if __name__ ==&quot; __ main __&quot;
は、スクリプトが(たとえば) python myscript.py
のようなコマンドを使用してコマンドラインから実行されるときに実行される部分です。 。
if __name__ ==&quot; __ main __&quot;:
はどうしますか?
__ 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()
問題のコードの仕組みである「How」については、さまざまな見解がありますが、私にとっては、「Why」を理解するまで意味がありませんでした。これは特に新しいプログラマーにとって役立つはずです。
ファイルを取得&quot; ab.py&quot;:
def a():
print('A function in ab file');
a()
2番目のファイル&quot; xy.py&quot;:
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
を実行すると、 abをインポートします
。 importステートメントはインポート時にモジュールをすぐに実行するため、 ab
の操作は残りの xy
の前に実行されます。 ab
で終了したら、 xy
に進みます。
インタープリターは、 __ name __
で実行されているスクリプトを追跡します。スクリプトを実行すると、名前に関係なく、インタープリターはそれを&quot; __ main __&quot;
と呼び、外部スクリプトの実行後に戻されるマスターまたは「ホーム」スクリプトになります。
この&quot; __ main __&quot;
スクリプトから呼び出される他のスクリプトには、そのファイル名が __ name __
として割り当てられます(例: __ name__ ==&quot; ab.py&quot ;
)。したがって、行 if __name__ ==&quot; __ main __&quot;:
は、最初に実行された「ホーム」スクリプトを解釈/解析するか、一時的に別のスクリプト(外部)を覗くかを決定するインタープリターのテストです)スクリプト。これにより、プログラマーは、スクリプトを直接実行する場合と外部から呼び出す場合とで、スクリプトの動作を変えることができます。
上記のコードをステップ実行して、何が起こっているのかを理解しましょう。まず、インデントされていない行と、スクリプトに表示される順序に注目します。関数または def
-ブロックは、呼び出されるまでそれ自体では何もしません。つぶやいた場合にインタープリターが言うこと:
- xy.pyを「ホーム」ファイルとして開きます。
__ name __
変数で&quot; __ main __&quot;
と呼びます。 -
__ name__ ==&quot; ab.py&quot;
でファイルをインポートして開きます。 - ああ、関数。覚えています。
- OK、関数
a()
;私はそれを学んだ。 ' abファイルの関数'を印刷しています。 - ファイルの終わり。
&quot; __ main __&quot;
に戻る! - ああ、関数。覚えています。
- もう1つ。
- 関数
x()
; OK、「周辺タスク:他のプロジェクトで役立つかもしれません」を印刷します。 - これは何ですか?
if
ステートメント。さて、条件が満たされている(変数__ name __
が&quot; __ main __&quot;
に設定されている)ので、main()
function and print ' main function:this is where where the action is '。
下の2行の意味:&quot;これが&quot; __ main __&quot;
または「home」スクリプトの場合、 main()
&quot;という関数を実行します。そのため、 def main():
ブロックが上部に表示されます。このブロックには、スクリプトの機能のメインフローが含まれています。
これを実装する理由
インポート文について前に言ったことを覚えていますか?モジュールをインポートするとき、それは単にそれを「認識」して、さらなる指示を待つだけではありません-それは実際にスクリプト内に含まれるすべての実行可能な操作を実行します。そのため、スクリプトの中身を main()
関数に入れると、それを効果的に隔離し、別のスクリプトによってインポートされたときにすぐに実行されないように隔離します。
再び、例外がありますが、一般的な慣行では、 main()
は通常外部から呼び出されません。もう1つ疑問に思うかもしれません。 main()
を呼び出していないのに、なぜスクリプトを呼び出しているのですか?それは、多くの人が、スクリプトとは独立して実行されるように構築されたスタンドアロン関数で構造化されているためです
モジュールに特定のステートメントがある場合( M.py
)、メインとして(インポートではなく)実行するときに実行したい場合、それらのステートメント(テストケース、文を印刷します)この if
ブロックの下。
デフォルトでは(インポートされていない、メインとして実行されているモジュールの場合)、変数 __ name __
は&quot; __ main __&quot;
に設定され、インポートされると< code> __ name __ 変数は異なる値、ほとんどの場合モジュールの名前( 'M'
)を取得します。
これは、モジュールのさまざまなバリエーションを一緒に実行し、特定の入力とアンプを分離するのに役立ちます。出力文およびテストケースがある場合。
要するに、この ' if __name__ ==&quot; main&quot;
'ブロックを使用して、モジュールのインポート時に(特定の)コードが実行されないようにします。
より抽象的な方法で答えを見てみましょう:
x.pyにこのコードがあるとします:
...
<Block A>
if __name__ == '__main__':
<Block B>
...
ブロックAおよびBは、「x.py」を実行しているときに実行されます。
ただし、別のモジュール「y.py」を実行している場合は、ブロックA(Bではなく)のみが実行されます。たとえば、x.yがインポートされ、そこからコードが実行されます(&quot; x.py&quot;の関数がy.pyから呼び出される場合など)。
簡単に言うと、 __ name __
は、スクリプトがメインモジュールとして実行されるか、インポートされたモジュールとして実行されるかを定義する各スクリプトに対して定義される変数です。
つまり、2つのスクリプトがある場合、
#script1.py
print "Script 1's name: {}".format(__name__)
and
#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__ ==&quot; __ main __&quot;:
コンテキスト内でのみ実行される場合)。一方、C / C ++では、それらの部分を別のモジュールに分けて、ファイルを含める必要があります。以下の状況を想像してください。
矢印はインポートリンクです。それぞれが前のモジュールコードをインクルードしようとする3つのモジュールには、6つのファイル(9つ、実装ファイルをカウント)と5つのリンクがあります。これは、特にライブラリとしてコンパイルされない限り、Cプロジェクトに他のコードを含めることを困難にします。 Pythonの場合:
モジュールを作成します。コードを使用する場合は、モジュールをインポートするだけで、 __ name __
変数を使用して、プログラムの実行可能部分とライブラリ部分を分離できます。
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.
検討:
if __name__ == "__main__":
main()
Pythonスクリプトの __ name __
属性が&quot; __ main __&quot;
かどうかを確認します。つまり、プログラム自体が実行される場合、属性は __ main __
になるため、プログラムが実行されます(この場合は main()
関数)。
ただし、Pythonスクリプトがモジュールで使用されている場合、 if
ステートメント以外のコードが実行されるため、 if \ __ name__ ==&quot; \ __ main __&quot;
は、プログラムがモジュールとして使用されているかどうかを確認するためだけに使用されるため、コードを実行するかどうかを決定します。
if __name__ == '__main __'
について何か説明する前に、 __ name __
とは何か、それが何をするのかを理解することが重要です。
__ name __
とは
__ name __
は DunderAlias です。グローバル変数(モジュールからアクセス可能)および globalと同様の方法で動作します
。
type(__ name __)
(&lt; class 'str'&gt;
を生成)で示される文字列(上記のグローバル)であり、組み込み 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 __
はファイルの名前を取ることに注意してください。実際のモジュールまたはパッケージパスのパスは指定されていませんが、これを可能にする独自のDunderAlias __ file __
があります。
__ name __
、メインファイル(またはプログラム)が常にに __ main __
が返され、モジュール/パッケージ、または他のPythonスクリプトから実行されているものは、元のファイルの名前を返します。
実践:
変数であることは、その値 を上書きできることを意味します(&quot; can&quot;は&quot; should&quot;を意味しません)。 __ 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 __
の動作がより明確になることがわかりました:
if
は指定された値がtrueの場合、コードブロックを含むフロー制御ステートメントが実行されます。 __ name __
は次のいずれかを取ることができます
__ main __
またはインポート元のファイル名。
これは、 __ name __
が __ main __
と等しい場合、ファイルはメインファイルであり、モジュールではなく実際に実行されている(またはインタープリターである)必要があることを意味しますまたはスクリプトにインポートされたパッケージ。
実際に __ name __
が __ main __
の値を取る場合、そのコードブロックにあるものはすべて実行されます。
これは、実行中のファイルがメインファイルである場合(またはインタープリターから直接実行している場合)、その条件を実行する必要があることを示しています。パッケージの場合はそうではなく、値は __ main __
にはなりません。
答えを深く、簡単な言葉で壊すのが最善だと思います:
__ name __
:Pythonのすべてのモジュールには、 __ name __
という特別な属性があります。
これは、モジュールの名前を返す組み込み変数です。
__ main __
:他のプログラミング言語と同様に、Pythonにも実行エントリポイント、つまりmainがあります。 '__ main __'
は、トップレベルコードが実行されるスコープの名前です。基本的に、Pythonモジュールを使用するには、スクリプトとして直接実行する方法とインポートする方法の2つの方法があります。モジュールがスクリプトとして実行されると、その __ name __
は __ main __
に設定されます。
したがって、モジュールがメインプログラムとして実行されると、 __ name __
属性の値が __ main __
に設定されます。それ以外の場合、 __ name __
の値は、モジュールの名前を含むように設定されます。
Pythonファイルがコマンドラインから呼び出される場合に特別です。これは通常、「main()」を呼び出すために使用されます。コマンドライン引数の処理など、他の適切な起動コードを機能させるか実行します。
それはいくつかの方法で書くことができます。もう1つは:
def some_function_for_instance_main():
dosomething()
__name__ == '__main__' and some_function_for_instance_main()
本番コードでこれを使用する必要があるとは言いませんが、「魔法の」ものは何もないことを示すのに役立ちます。 if __name__ == '__main __'
について。 Pythonファイルでメイン関数を呼び出すための良い規則です。
システム(Pythonインタープリター)がソースファイル(モジュール)に提供する変数は多数あります。いつでも値を取得できますので、 __ name __ 変数/属性に注目しましょう:
Pythonはソースコードファイルを読み込むと、その中にあるすべてのコードを実行します。 (ファイルで定義されているすべてのメソッドと関数を呼び出すわけではありませんが、それらを定義することに注意してください。)
インタプリタはソースコードファイルを実行する前に、そのファイルにいくつかの特別な変数を定義します。 __ name __ は、Pythonが各ソースコードファイルに対して自動的に定義する特殊変数の1つです。
Pythonがこのソースコードファイルをメインプログラム(つまり、実行するファイル)として読み込んでいる場合、このファイルの特別な __ name __ 変数に値&quot; __ main __&quotを設定します; 。
これが別のモジュールからインポートされている場合、 __ 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 __ の値が&quot; main &quot;と等しくないため、別のモジュールが呼び出し/インポートしている場合、コードブロックは実行されません。その特定のインスタンスで。
これがお役に立てば幸いです。
if __name__ ==&quot; __ main __&quot;:
は基本的にトップレベルのスクリプト環境であり、インタープリターを指定します(「最初に実行される最高の優先順位があります」)。
'__ main __'
は、トップレベルコードが実行されるスコープの名前です。モジュールの __ name __
は、標準入力、スクリプト、またはインタラクティブプロンプトから読み取られたときに '__ main __'
と等しく設定されます。
if __name__ == "__main__":
# Execute only if run as a script
main()
理由
if __name__ == "__main__":
main()
主にインポートロックを回避する コードを直接インポートしたことから発生する問題。ファイルが直接呼び出された場合( __ name__ ==&quot; __ main __&quot;
の場合)、 main()
を実行しますが、コードがインポートされた場合、インポーターはインポートロックの問題を回避するために、真のメインモジュールからコードを入力します。
副作用は、複数のエントリポイントをサポートする方法論に自動的にサインオンすることです。 main()
をエントリポイントとして使用してプログラムを実行できますが、する必要はありません。 setup.py
は main()
を想定していますが、他のツールは代替エントリポイントを使用します。たとえば、ファイルを gunicorn
プロセスとして実行するには、 main()
ではなく、 app()
関数を定義します。 setup.py
と同様に、 gunicorn
はコードをインポートするため、インポート中は何も実行したくない(インポートロックの問題のため)。
このページの回答全体を読みました。私は、あなたが事を知っていれば、あなたがそれらの答えを確実に理解するだろうと言うでしょう、さもなければ、あなたはまだ混乱しています。
短くするには、いくつかのポイントを知る必要があります:
-
import a
アクションは、実際に&quot; a&quot; で実行できるすべてを実行します
-
ポイント1のため、「a」ですべてを実行したくない場合があります。インポートするとき
-
ポイント2の問題を解決するために、Pythonでは条件チェックを行うことができます
-
__ name __
は、すべての.pyモジュールの暗黙的な変数です。 a.pyがインポートされると、a.pyモジュールの__ name __
の値がそのファイル名&quot; a&quot;に設定されます。 &quot; python a.py&quot;を使用してa.pyを直接実行すると、a.pyがエントリポイントになるため、a.pyモジュールの__ name __
の値は文字列__ main __
-
Pythonが各モジュールの変数
__ name __
を設定するメカニズムに基づいて、ポイント3を達成する方法を知っていますか?答えはかなり簡単ですよね? if条件を入れます:if __name__ ==&quot; __ main __&quot ;: ...
;機能的なニーズに応じて、__ name__ ==&quot; a&quot;
の場合でも置くことができます
Pythonが特別なのはポイント4です!残りは基本的なロジックです。
検討:
print __name__
上記の出力は __ main __
です。
if __name__ == "__main__":
print "direct method"
上記の文は真であり、&quot; direct method&quot; を出力します。このクラスを別のクラスにインポートした場合、&quot; direct method&quot; は出力されません。インポート中に、 __ name__が&quot; first model name&quot;
に設定されるためです。
ファイルをスクリプトおよびインポート可能なモジュールとして使用可能にすることができます。
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]))
この回答は、Pythonを学習しているJavaプログラマ向けです。 通常、すべてのJavaファイルには1つのパブリッククラスが含まれます。このクラスは次の2つの方法で使用できます。
-
他のファイルからクラスを呼び出します。呼び出し元のプログラムにインポートするだけです。
-
テスト目的で、クラスをスタンドアロンで実行します。
後者の場合、クラスにはpublic static void main()メソッドを含める必要があります。 Pythonでは、この目的はグローバルに定義されたラベル '__ main __'
によって提供されます。
この.pyファイルが他の.pyファイルによってインポートされる場合、&quot; ifステートメント&quot;の下のコード実行されません。
この.pyがシェルで python this_py.py
によって実行される場合、またはWindowsでダブルクリックされる場合。 &quot; ifステートメント&quot;の下のコード実行されます。
通常、テスト用に作成されています。
ファイルを作成、 a.py :
print(__name__) # It will print out __main__
__ name __
は、そのファイルが直接実行され、これがメインファイルであることを示す場合、常に __ main __
と等しくなります。
同じディレクトリに別のファイル b.py を作成します:
import a # Prints a
実行します。 a 、つまりインポートされたファイルの名前を印刷します。
つまり、同じファイルの2つの異なる動作を示すために、これは一般的に使用されるトリックです:
# Code to be run when imported into another python file
if __name__ == '__main__':
# Code to be run only when run directly
name == ' main 'の場合:
__ name__ == '__main __':
が頻繁に発生するかどうかを確認します。
モジュールがインポートされているかどうかを確認します。
つまり、 if
ブロック内のコードは、コードが直接実行されたときにのみ実行されます。ここで、直接
は、インポートされない
を意味します。
モジュールの名前を出力する簡単なコードを使用して、それが何をするのか見てみましょう:
# 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__
すべての回答で機能についてほとんど説明しました。しかし、この概念をさらに明確にするのに役立つかもしれない、その使用法の一例を提供します。
a.pyとb.pyの2つのPythonファイルがあると仮定します。現在、a.pyはb.pyをインポートします。 &quot; import b.py&quot;のa.pyファイルを実行します。コードが最初に実行されます。残りのa.pyコードを実行する前に、ファイルb.pyのコードを完全に実行する必要があります。
b.pyコードには、そのファイルb.py専用のコードがいくつかあり、b.pyファイルをインポートした他のファイル(b.pyファイル以外)は不要です。実行します。
それで、このコード行がチェックします。コードを実行しているメインファイル(つまり、b.py)であり、この場合は実行されていない(a.pyが実行されているメインファイル)場合、コードのみが実行されます。
単に、 C プログラミング言語の main
関数のようなファイルを実行するためのエントリポイントです。
Pythonのすべてのモジュールには、 name と呼ばれる属性があります。モジュールが直接実行される場合、 name 属性の値は「 main 」です。それ以外の場合、 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を呼び出したときに、test.pyの name ループが実行されない場合。