if __== "__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 __== "__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 __guard")
if __== '__main__':
functionA()
functionB()
print("after __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.
__= "__main__"
あなたのモジュールが他の人によってインポートされたとき
一方、他のモジュールがメインプログラムであり、それがあなたのモジュールをインポートすると仮定します。これは、メインプログラム、またはメインプログラムがインポートする他のモジュールに次のようなステートメントがあることを意味します。
# Suppose this is in some other main program.
import foo
この場合、インタプリタはあなたのモジュールのファイル名foo.py
を見て、.py
を取り除き、その文字列をあなたのモジュールの__name__
変数に割り当てます。
# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__= "foo"
特殊変数が設定された後、インタプリタはモジュール内のすべてのコードを一度に1ステートメントずつ実行します。この説明に沿って進むことができるように、コードサンプルがある側に別のウィンドウを開くことができます。
常に
文字列"before import"
を(引用符なしで)表示します。
それは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")
文字列"before functionA"
を表示します。
def
ブロックを実行して関数オブジェクトを作成し、その関数オブジェクトをfunctionA
という変数に割り当てます。
文字列"before functionB"
を表示します。
2番目のdef
ブロックを実行して別の関数オブジェクトを作成し、それをfunctionB
という変数に代入します。
文字列"before __guard"
を表示します。
あなたのモジュールがメインプログラムである場合のみ
__name__
が実際に"__main__"
に設定されていることがわかり、それは2つの関数を呼び出し、文字列"Function A"
と"Function B 10.0"
を出力します。あなたのモジュールが他のモジュールによってインポートされたときのみ
__name__
は"foo"
ではなく"__main__"
となり、if
ステートメントの本体はスキップされます。常に
"after __guard"
が表示されます。要約
まとめると、2つのケースで印刷される内容は次のとおりです。
# What gets printed if foo is the main program
before import
before functionA
before functionB
before __guard
Function A
Function B 10.0
after __guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __guard
after __guard
あなたは自然になぜ誰かがこれを望んでいるのだろうかと思うかもしれません。まあ、時にはあなたは.py
ファイルを書きたいと思うかもしれません。それはモジュールとして他のプログラムやモジュールによって使用され、メインプログラムとして実行されることができます。例:
あなたのモジュールはライブラリですが、あなたはそれがいくつかのユニットテストまたはデモを実行するスクリプトモードを持ちたいです。
あなたのモジュールはメインプログラムとして使われるだけですが、それはいくつかの単体テストを持っています、そしてテストフレームワークはあなたのスクリプトのような.py
ファイルをインポートして特別なテスト関数を実行することによって働きます。モジュールをインポートしているからといって、スクリプトを実行してはいけません。
あなたのモジュールは主にメインプログラムとして使用されていますが、それはまた上級ユーザー向けのプログラマ向けAPIを提供します。
これらの例以外にも、Pythonでスクリプトを実行することで、いくつかの魔法の変数を設定してそのスクリプトをインポートするだけのことができます。スクリプトを「実行」することは、スクリプトのモジュールをインポートすることの副作用です。
質問:__name__
チェックブロックを複数持つことはできますか?答え:そうするのは不思議ですが、言語があなたを止めることはありません。
次がfoo2.py
にあるとします。あなたがコマンドラインでpython 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 __== "__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
__= "__main__"
def bar():
print("bar")
print("before __guard")
if __== "__main__":
bar()
print("after __guard")
スクリプトをコマンドとしてPythonインタプリタに渡して実行すると、
python myscript.py
インデントレベル0のすべてのコードが実行されます。定義された関数やクラスは定義されていますが、それらのコードは実行されません。他の言語とは異なり、自動的に実行されるmain()
関数はありません - main()
関数は、暗黙のうちに最上位レベルのすべてのコードです。
この場合、最上位コードはif
ブロックです。 __name__
は、現在のモジュールの名前に評価される組み込み変数です。ただし、(上記のmyscript.py
のように)モジュールが直接実行されている場合は、代わりに__name__
が文字列"__main__"
に設定されます。したがって、テストすることで、スクリプトが直接実行されているのか、他のものによってインポートされているのかをテストできます。
if __== "__main__":
...
あなたのスクリプトが他のモジュールにインポートされている場合、そのさまざまな関数とクラス定義がインポートされ、そのトップレベルのコードが実行されますが、上記のif
節のthen本体のコードは条件として実行されません満たされていません。基本的な例として、次の2つのスクリプトを考えてください。
# file one.py
def func():
print("func() in one.py")
print("top-level in one.py")
if __== "__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 __== "__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__"
と等しくなります。
__name__
変数(imho)の最も簡単な説明は次のとおりです。
以下のファイルを作成してください。
# a.py
import b
そして
# b.py
print "Hello World from %s!" % __name__
if __== '__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
と評価され、実行されています。
if __== "__main__":
は何をしますか?
基本を概説するには:
プログラムへのエントリポイントであるモジュール内のグローバル変数__name__
は'__main__'
です。それ以外の場合は、モジュールをインポートする名前です。
したがって、if
ブロックの下のコードは、モジュールがプログラムへのエントリポイントである場合にのみ実行されます。
これにより、インポート時に下のコードブロックを実行することなく、モジュール内のコードを他のモジュールからインポートできます。
なぜ私たちはこれが必要なのですか?
モジュールとして使用するように設計されたPythonスクリプトを書いているとしましょう。
def do_important():
"""This function does something very important"""
couldは、この関数の呼び出しを下部に追加してモジュールをテストします。
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)内では、"__main__"
からすべてを実行しています。
したがって、実行する前に確認する場合:
if __== "__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 __== '__main__':
main()
これで、モジュールをプライマリモジュールとして実行した場合に実行されるモジュールの最後の最終関数ができました。
main
関数を実行せずにモジュールとその関数とクラスを他のスクリプトにインポートできるようにし、異なる'__main__'
モジュールから実行するときにモジュール(およびその関数とクラス)を呼び出すこともできます。すなわち.
import important
important.main()
このイディオムは__main__
モジュールの説明のPythonドキュメントにもあります。 そのテキストの状態:
このモジュールは、インタープリターのメインプログラムが実行される(それ以外の場合は匿名の)スコープを表します。標準入力、スクリプトファイル、または対話型プロンプトから読み取られたコマンドです。この環境では、慣用的な「条件付きスクリプト」スタンザによってスクリプトが実行されます。
if __== '__main__': main()
if __== "__main__"
は、スクリプトがpython myscript.py
のようなコマンドを使用してコマンドラインから実行されるときに実行される部分です。
if __== "__main__":
は何をしますか?
__name__
は、すべての名前空間に存在するグローバル変数です(Pythonでは、globalは実際には モジュールレベル を意味します)。通常はモジュールの名前です(str
型として)。
しかし、mycode.pyのように、あなたが実行するPythonプロセスの中では、唯一の特別な場合として:
python mycode.py
それ以外の場合は匿名のグローバル名前空間には、その'__main__'
に__name__
の値が割り当てられます。
したがって、 最後の行 を含める
if __== '__main__':
main()
スクリプトの独自に定義されたmain
関数が実行されます。
この構文を使用することによるもう1つの利点は、コードを別のスクリプトのモジュールとしてインポートして、プログラムが次の場合にメイン関数を実行することもできます。
import mycode
# ... any amount of other code
mycode.main()
ここでは、問題のコードの仕組みである「How」についてさまざまな見解がありますが、私にとっては、「Why」を理解するまで意味がありませんでした。これは特に新しいプログラマーにとって役立つはずです。
ファイル「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 __== "__main__":
main()
このコードは実際に何をしていますか?
xy.py
を実行すると、import ab
になります。 importステートメントはインポート時にモジュールをすぐに実行するため、ab
の操作はxy
の残りの前に実行されます。 ab
で終了したら、xy
で続行します。
インタープリターは、__name__
で実行されているスクリプトを追跡します。スクリプトを実行すると、名前に関係なく、インタープリターは"__main__"
と呼び、外部スクリプトの実行後に戻るマスターまたは「ホーム」スクリプトにします。
この"__main__"
スクリプトから呼び出される他のスクリプトには、__name__
としてファイル名が割り当てられます(例:__== "ab.py"
)。したがって、if __== "__main__":
行は、最初に実行された「ホーム」スクリプトを解釈/解析するか、一時的に別の(外部)スクリプトを覗くかを判断するためのインタープリターのテストです。これにより、プログラマーは、スクリプトを直接実行する場合と外部から呼び出す場合に、スクリプトの動作を変えることができます。
上記のコードをステップ実行して、何が起こっているのかを理解します。まず、インデントされていない行と、スクリプトに表示される順序に注目します。関数-またはdef
-ブロックは、呼び出されるまでそれ自体では何もしません。つぶやいた場合、通訳は次のように言います。
"__main__"
変数で__name__
と呼びます。__== "ab.py"
でファイルをインポートして開きます。a()
;私はそれを学んだ。 'Aファイルの関数'を印刷しています。"__main__"
に戻る!x()
; OK、 'peripheral task:他のプロジェクトで役に立つかもしれません'.if
ステートメント。さて、条件が満たされている(変数__name__
が"__main__"
に設定されている)ので、main()
関数を入力し、 'main関数を出力します:これがアクションの場所です '。下の2行は、「これが"__main__"
または 'home'スクリプトである場合、main()
という関数を実行します。そのため、スクリプト機能のメインフローを含むdef main():
ブロックが上部に表示されます。
なぜこれを実装するのですか?
インポートステートメントについて前に言ったことを覚えていますか?モジュールをインポートするとき、それは単にそれを「認識」して、さらなる指示を待つだけではありません-実際にスクリプト内に含まれるすべての実行可能な操作を実行します。したがって、スクリプトの内容をmain()
関数に入れると、それを効果的に隔離し、別のスクリプトによってインポートされたときにすぐに実行されないように隔離します。
再び、例外がありますが、一般的な慣行は、main()
は通常外部から呼び出されないことです。ですから、もう1つ疑問に思うかもしれません。main()
を呼び出していないのに、なぜスクリプトを呼び出しているのですか?多くの人が、ファイル内の残りのコードから独立して実行されるように構築されたスタンドアロン関数でスクリプトを構成しているためです。その後、スクリプトの本文のどこかで呼び出されます。これは私にこれをもたらします:
しかし、コードはそれなしで動作します
はい、そうです。これらの個別の関数は、main()
関数内に含まれていないインラインスクリプトから呼び出すことができます。あなたが(私がプログラミングの初期の学習段階にいるように)あなたが必要とするものを正確に実行するインラインスクリプトを構築することに慣れているなら、あなたはその操作が再び必要になったら再びそれを理解しようとします..まあ、あなたはコードのこの種の内部構造に慣れていません、なぜならそれは構築するのがより複雑で、読むのが直観的でないからです。
しかし、それはおそらく関数を外部から呼び出すことができないスクリプトです。なぜなら、そうするとすぐに変数の計算と割り当てが開始されるからです。また、関数を再利用しようとしている場合、新しいスクリプトが古い変数と十分に密接に関連しているため、変数が競合する可能性があります。
独立した機能を分割する場合、以前の作業を別のスクリプトに呼び出すことで、以前の作業を再利用することができます。たとえば、「example.py」は「xy.py」をインポートし、x()
を呼び出し、「xy.py」の「x」関数を使用します。 (たぶん、与えられたテキスト文字列の3番目の単語を大文字にする、数字のリストからNumPy配列を作成してそれらを二乗する、または3Dサーフェスをトレンド除去することです。可能性は無限です。)
(余談ですが、 この質問 には@kindallによる答えが含まれています。これは最終的に私を理解するのに役立ちました-理由ではなく、理由です。残念なことに this one =、これは間違いだと思います。)
モジュール(M.py
)の中に、それがメインとして実行される(インポートされない)ときに実行されることを望む特定のステートメントがある場合、それらのステートメント(テストケース、printステートメント)をこのif
ブロックの下に置くことができます。
デフォルト(モジュールがmainとして実行されているとき、インポートされていないとき)は__name__
変数が"__main__"
に設定され、インポートされるとき__name__
変数は異なる値(おそらくモジュールの名前('M'
))を取得します。これは、モジュールのさまざまなバリエーションをまとめて実行したり、それらの特定の入出力文を分離したり、テストケースがある場合にも役立ちます。
手短に言えば で、モジュールのインポート時に(特定の)コードが実行されないようにするには、この 'if __== "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++のように、コードを書くだけで構造上の問題を心配する必要がないので、これは素晴らしいことです。ライブラリとして使用することはできません。
例えば、あなたがPythonスクリプトを書いて、それが何か素晴らしいことをしていて、他の目的のために役立つたくさんの関数を実装しているとしましょう。それらを使用したいのであれば、スクリプトをインポートしてプログラムを実行せずに使用することができます(コードがif __== "__main__":
コンテキスト内でのみ実行されることを考えると)。 C/C++では、それらの部分を別々のモジュールに分割してファイルに含める必要があります。以下の状況を想像してください。
矢印はインポートリンクです。それぞれが以前のモジュールコードをインクルードしようとしている3つのモジュールに対して、6つのファイル(9つ、実装ファイルを数えます)と5つのリンクがあります。これは、特にライブラリとしてコンパイルされていない限り、他のコードをCプロジェクトに含めることを難しくします。今度はそれをPython用に描きます。
あなたはモジュールを書きます、そして、誰かがあなたのコードを使用したいなら彼らはそれを単にインポートします、そして__name__
変数はライブラリ部分からプログラムの実行可能部分を分けるのを助けることができます。
もっと抽象的な方法で答えを見てみましょう。
このコードがx.pyにあるとします。
...
<Block A>
if __== '__main__':
<Block B>
...
ブロックAとBは、 "x.py"を実行しているときに実行されます。
しかし、たとえば "y.py"という別のモジュールを実行しているときは、ブロックA(Bではなく)だけが実行されます。ここでは、xyがインポートされ、そこからコードが実行されます。 y.pyから呼び出されます。
対話的にPythonを実行すると、ローカルの__name__
変数に__main__
の値が割り当てられます。同様に、Pythonモジュールを他のモジュールにインポートするのではなく、コマンドラインから実行すると、実際のモジュール名ではなく、その__name__
属性に値__main__
が割り当てられます。このようにして、モジュールは自分自身の__name__
値を調べて、他のプログラムのサポートとして、またはコマンドラインから実行されるメインアプリケーションとしての使用方法を自分で判断することができます。したがって、次の慣用句はPythonモジュールではかなり一般的です。
if __== '__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 __== "__main__":
main()
Pythonスクリプトの__name__
属性が"__main__"
であるかどうかを調べます。つまり、プログラム自体が実行されると、属性は__main__
になり、プログラムが実行されます(この場合はmain()
関数)。
ただし、Pythonスクリプトがモジュールによって使用されている場合は、if
ステートメント以外のコードが実行されるため、プログラムがモジュールとして使用されているかどうかを確認するためだけにif \__== "\__main__"
が使用されます。
if __== '__main__'
について説明する前に、__name__
とは何か、それが何をするかを理解することが重要です。
__name__
とは?
__name__
は DunderAlias -グローバル変数(モジュールからアクセス可能)と考えることができ、 global
と同様の方法で動作します。
type(__name__)
(<class 'str'>
を生成)で示される文字列(上記のようにグローバル)であり、 Python と 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__
、メインファイル(またはプログラム)がalways return __main__
であり、モジュール/パッケージであるか、または他のPythonスクリプトから実行されている場合、元のファイルの名前を返します。
実践:
変数であるということは、その値canが上書きされることを意味し( "can"は "should"を意味しません)、__name__
の値を上書きすると読みにくくなります。何らかの理由でそれをしないでください。変数が必要な場合は、新しい変数を定義します。
__name__
の値は__main__
またはファイルの名前であると常に想定されています。もう一度このデフォルト値を変更すると、より良い混乱が発生し、さらに問題が発生します。
例:
>>> __= 'Horrify' # Change default from __main__
>>> if __== 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>
一般に、if __== '__main__'
をスクリプトに含めることをお勧めします。
今すぐ答える
if __== '__main__'
:
これで__name__
の動作が明らかになりました:
if
は、指定された値がtrueの場合に実行されるコードブロックを含むフロー制御ステートメントです。 __name__
は__main__
またはインポート元のファイル名のいずれかを取ることができることを見てきました。
つまり、__name__
が__main__
と等しい場合、ファイルはメインファイルであり、スクリプトにインポートされたモジュールまたはパッケージではなく、実際に実行されている(またはインタープリターである)必要があります。
確かに__name__
が__main__
の値を取る場合、そのコードブロックにあるものはすべて実行されます。
これは、実行中のファイルがメインファイルである場合(またはインタープリターから直接実行している場合)、その条件を実行する必要があることを示しています。パッケージの場合はそうではなく、値は__main__
にはなりません。
モジュール:
__name__
はモジュールで使用してモジュールの名前を定義することもできます
バリアント:
__name__
を使用して、あまり一般的ではないが有用な他の操作を実行することもできます。その一部を以下に示します。
ファイルがモジュールまたはパッケージの場合のみ実行:
if __!= '__main__':
# Do some useful things
ファイルがメインの場合はある条件を実行し、そうでない場合は別の条件を実行します:
if __== '__main__':
# Execute something
else:
# Do some useful things
また、これを使用して、ライブラリを入念に使用することなく、パッケージおよびモジュールで実行可能なヘルプ機能/ユーティリティを提供できます。
また、コマンドラインからモジュールをメインスクリプトとして実行できるため、非常に便利です。
私はそれが深くそして簡単な言葉で答えを破ることが最善だと思います:
__name__
:Pythonのすべてのモジュールは__name__
という特別な属性を持っています。モジュールの名前を返す組み込み変数です。
__main__
:他のプログラミング言語と同様に、Pythonにも実行エントリポイント、つまりmainがあります。 '__main__'
は、トップレベルのコードが実行されるスコープの名前です 。基本的には、Pythonモジュールを使用する2つの方法があります。スクリプトとして直接実行するか、インポートします。モジュールがスクリプトとして実行されると、その__name__
は__main__
に設定されます。
したがって、__name__
属性の値は、モジュールがメインプログラムとして実行されるときに__main__
に設定されます。そうでなければ、__name__
の値はモジュールの名前を含むように設定されます。
これは、Pythonファイルがコマンドラインから呼び出されたときに特別です。これは通常、 "main()"関数の呼び出しや、たとえばコマンドライン引数処理などの他の適切な起動コードの実行に使用されます。
それはいくつかの方法で書くことができます。もう一つは:
def some_function_for_instance_main():
dosomething()
__== '__main__' and some_function_for_instance_main()
私はあなたが本番用コードでこれを使うべきだと言っているのではありませんが、それはif __== '__main__'
に関して「魔法のような」ものが何もないことを説明するのに役立ちます。 Pythonファイルでmain関数を呼び出すのは良い習慣です。
システム(Pythonインタプリタ)がソースファイル(モジュール)に提供する変数はたくさんあります。いつでも好きなときにそれらの値を取得することができますので、 __ variable /属性に焦点を当てましょう。
Pythonがソースコードファイルをロードすると、そこにあるすべてのコードを実行します。 (ファイルで定義されているすべてのメソッドと関数を呼び出すわけではありませんが、それらは定義されています)。
ただし、インタプリタがソースコードファイルを実行する前に、そのファイルに対していくつかの特別な変数を定義します。 __ は、Pythonが各ソースコードファイルに対して自動的に定義する特殊変数の1つです。
Pythonがこのソースコードファイルをメインプログラム(つまり、実行するファイル)としてロードしている場合、このファイルの特別な __ 変数に "__main__" という値を設定します。
これが他のモジュールからインポートされている場合、 __ はそのモジュールの名前に設定されます。
だから、あなたの例で部分的に:
if __== "__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))
モジュールを直接実行した場合にのみ実行されます。 __ の値がその特定のインスタンスでは " main "に等しくないため、別のモジュールがそれを呼び出しているかインポートしている場合、コードブロックは実行されません。
これが役立つことを願っています。
if __== "__main__":
は基本的にトップレベルのスクリプト環境であり、それはそのインタプリタを指定します(「私が最初に実行されるのが最高の優先順位です」)。
'__main__'
は、トップレベルのコードが実行されるスコープの名前です。モジュールの__name__
は、標準入力、スクリプト、または対話型プロンプトから読み込まれたときに'__main__'
に等しく設定されます。
if __== "__main__":
# Execute only if run as a script
main()
の理由
if __== "__main__":
main()
コードの直接インポート _から発生する可能性のある インポートロック 問題を回避するためのものです。ファイルが直接呼び出された場合(__== "__main__"
の場合)はmain()
を実行しますが、コードがインポートされた場合は、インポートロックの問題を回避するためにインポーターが本当のメインモジュールからコードを入力する必要があります。
副作用は、複数のエントリポイントをサポートする方法論に自動的にサインオンすることです。エントリポイントとしてmain()
を使用してプログラムを実行することができます、 しかし、 をする必要はありません。 setup.py
はmain()
を期待していますが、他のツールは代替のエントリポイントを使用します。たとえば、ファイルをgunicorn
プロセスとして実行するには、app()
ではなくmain()
関数を定義します。 setup.py
と同じように、gunicorn
はコードをインポートするので、インポート中に何もしたくない(インポートロックの問題のため)。
私はこのページの答えを通してずっと読んできました。あなたがそのことを知っていれば、あなたはそれらの答えを確実に理解するでしょう、そうでなければ、あなたはまだ混乱しています。
簡単に言うと、いくつかの点を知っておく必要があります。
import a
アクションは実際には "a"で実行できるものすべてを実行します。
ポイント1のため、インポート時にすべてを "a"で実行したくない場合があります。
ポイント2の問題を解決するために、pythonでは条件チェックをすることができます。
__name__
はすべての.pyモジュールで暗黙の変数です。 a.pyがインポートされると、a.pyモジュールの__name__
の値はそのファイル名 "a"に設定されます。 a.pyがエントリポイントであることを意味する "python a.py"を使用してa.pyが直接実行されると、a.pyモジュールの__name__
の値は文字列__main__
に設定されます。
Pythonがモジュールごとに変数__name__
を設定する仕組みに基づいて、ポイント3を達成する方法を知っていますか?答えはかなり簡単ですね。 if条件を入れてください:if __== "__main__": ...
;あなたの機能上の必要性に応じて__== "a"
ならあなたも置くことができます
Pythonが特別であるという重要なことはポイント4です。あとは基本的なロジックです。
検討してください:
print __name__
上記の出力は__main__
です。
if __== "__main__":
print "direct method"
上記の説明は真実であり、 "direct method" を出力します。このクラスを別のクラスにインポートした場合、それが表示されないとします。 "直接メソッド" インポート中に__equal to "first model name"
が設定されるためです。
ファイルを スクリプト および インポート可能モジュール として使用できるようにすることができます。
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 __== "__main__":
import sys
fib(int(sys.argv[1]))
この答えは、Pythonを学ぶJavaプログラマーのためのものです。すべてのJavaファイルには通常、パブリッククラスが1つ含まれています。そのクラスを使用する方法は2つあります。
他のファイルからクラスを呼び出します。呼び出し側プログラムにインポートするだけです。
テスト目的で、クラスをスタンドアロンで実行します。
後者の場合、クラスはpublic static void main()メソッドを含むべきです。 Pythonでは、この目的はグローバルに定義されたラベル'__main__'
によって行われます。
この.pyファイルが他の.pyファイルによってインポートされた場合、 "the ifステートメント"の下のコードは実行されません。
この.pyがShellの下でpython this_py.py
によって実行された場合、またはWindowsでダブルクリックされた場合「if文」の下のコードが実行されます。
通常はテスト用に書かれています。
ファイルを作成します。 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 __== '__main__':
# Code to be run only when run directly
__== '__main__':
がかなり頻繁にあるかどうか見ます。
モジュールがインポートされているかどうかをチェックします。
つまり、if
ブロック内のコードは、コードが直接実行されるときにのみ実行されます。ここでdirectly
はnot imported
を意味します。
モジュールの名前を表示する簡単なコードを使ってそれが何をするのか見てみましょう:
# test.py
def test():
print('test module name=%s' %(__name__))
if __== '__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をインポートします。 "import b.py"コードが最初に実行される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 __== "__main__":
print("Value of __is: ", __name__)
print("Going to call hello_world")
hello_world()
これを直接実行できます
python test.py
出力
Value of __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のloop nameが実行されない場合は自明です。
pythonインタープリターが特定のモジュールを実行している場合、__name__
グローバル変数の値は"__main__"
になります
def a():
print("a")
def b():
print("b")
if __== "__main__":
print ("you can see me" )
a()
else:
print ("You can't see me")
b()
このスクリプトを実行すると、あなたは私を見ることができます
a
このファイルをインポートすると、AをファイルBにインポートしてファイルBを実行すると、ファイルAのif __== "__main__"
がfalseになるため、You ca n't see meと出力されます
b