Was macht der 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))
Immer wenn der Python -Interpreter eine Quelldatei liest, werden zwei Aktionen ausgeführt:
es setzt ein paar spezielle Variablen wie __name__
und dann
es führt den gesamten Code aus, der in der Datei enthalten ist.
Mal sehen, wie das funktioniert und wie es mit Ihrer Frage nach den __name__
-Überprüfungen zusammenhängt, die wir immer in Python -Skripten sehen.
Lassen Sie uns ein etwas anderes Codebeispiel verwenden, um die Funktionsweise von Importen und Skripten zu untersuchen. Angenommen, das Folgende befindet sich in einer Datei mit dem Namen 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")
Wenn der Interpeter Python eine Quelldatei liest, definiert er zuerst einige spezielle Variablen. In diesem Fall interessiert uns die Variable __name__
.
Wenn Ihr Modul das Hauptprogramm ist
Wenn Sie Ihr Modul (die Quelldatei) als Hauptprogramm ausführen, z.
python foo.py
der Interpreter weist der Variablen "__main__"
die fest codierte Zeichenfolge __name__
zu, d. h.
# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__= "__main__"
Wenn Ihr Modul von einem anderen importiert wird
Angenommen, ein anderes Modul ist das Hauptprogramm und importiert Ihr Modul. Dies bedeutet, dass es im Hauptprogramm oder in einem anderen Modul eine Anweisung wie diese gibt, die das Hauptprogramm importiert:
# Suppose this is in some other main program.
import foo
In diesem Fall überprüft der Interpreter den Dateinamen Ihres Moduls, foo.py
, entfernt den .py
und weist diesen String der __name__
-Variablen Ihres Moduls zu, d. H.
# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__= "foo"
Nachdem die speziellen Variablen eingerichtet wurden, führt der Interpreter den gesamten Code im Modul einzeln aus. Möglicherweise möchten Sie ein anderes Fenster an der Seite mit dem Codebeispiel öffnen, damit Sie dieser Erklärung folgen können.
Immer
Es druckt den String "before import"
(ohne Anführungszeichen).
Es lädt das Modul math
und weist es einer Variablen mit dem Namen math
zu. Dies entspricht dem Ersetzen von import math
durch Folgendes (beachten Sie, dass __import__
eine Low-Level-Funktion in Python ist, die eine Zeichenfolge akzeptiert und den tatsächlichen Import auslöst):
# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
Es wird die Zeichenfolge "before functionA"
ausgegeben.
Es führt den Block def
aus, erstellt ein Funktionsobjekt und weist dieses Funktionsobjekt einer Variablen mit dem Namen functionA
zu.
Es wird die Zeichenfolge "before functionB"
ausgegeben.
Es führt den zweiten Block def
aus, erstellt ein weiteres Funktionsobjekt und weist es dann einer Variablen mit dem Namen functionB
zu.
Es wird die Zeichenfolge "before __guard"
ausgegeben.
Nur wenn Ihr Modul das Hauptprogramm ist
__name__
in der Tat auf "__main__"
gesetzt wurde und die beiden Funktionen aufruft, wobei die Zeichenfolgen "Function A"
und "Function B 10.0"
gedruckt werden.Nur wenn Ihr Modul von einem anderen importiert wird
__name__
"foo"
, nicht "__main__"
, und das wird es Überspringen Sie den Text der Anweisung if
.Immer
"after __guard"
ausgegeben.Zusammenfassung
Zusammenfassend ist hier, was in den beiden Fällen gedruckt werden würde:
# 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
Sie mögen sich natürlich fragen, warum irgendjemand das wollen würde. Nun, manchmal möchten Sie eine .py
-Datei schreiben, die sowohl von anderen Programmen und/oder Modulen als Modul verwendet werden kann, als auch als Hauptprogramm selbst ausgeführt werden kann. Beispiele:
Ihr Modul ist eine Bibliothek, aber Sie möchten einen Skriptmodus, in dem einige Komponententests oder eine Demo ausgeführt werden.
Ihr Modul wird nur als Hauptprogramm verwendet, verfügt jedoch über einige Komponententests. Das Testframework importiert .py
-Dateien wie Ihr Skript und führt spezielle Testfunktionen aus. Sie möchten nicht, dass das Skript ausgeführt wird, nur weil das Modul importiert wird.
Ihr Modul wird hauptsächlich als Hauptprogramm verwendet, bietet aber auch eine programmiererfreundliche API für fortgeschrittene Benutzer.
Abgesehen von diesen Beispielen ist es elegant, dass das Ausführen eines Skripts in Python nur einige magische Variablen einrichtet und das Skript importiert. "Ausführen" des Skripts ist ein Nebeneffekt beim Importieren des Skriptmoduls.
Frage: Kann ich mehrere __name__
Prüfblöcke haben? Antwort: Es ist seltsam, das zu tun, aber die Sprache wird Sie nicht aufhalten.
Angenommen, das Folgende ist in foo2.py
. Was passiert, wenn Sie in der Befehlszeile python foo2.py
sagen? Warum?
# 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__
Check-in foo3.py
entfernen:# 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")
Wenn Ihr Skript ausgeführt wird, indem es als Befehl an den Python -Interpreter übergeben wird,
python myscript.py
der gesamte Code auf Einrückungsstufe 0 wird ausgeführt. Definierte Funktionen und Klassen sind zwar definiert, aber keiner ihrer Codes wird ausgeführt. Im Gegensatz zu anderen Sprachen gibt es keine Funktion main()
, die automatisch ausgeführt wird - die Funktion main()
ist implizit der gesamte Code auf der obersten Ebene.
In diesem Fall ist der Code der obersten Ebene ein if
-Block. __name__
ist eine eingebaute Variable, die den Namen des aktuellen Moduls ergibt. Wenn jedoch ein Modul direkt ausgeführt wird (wie in myscript.py
oben), wird stattdessen __name__
auf die Zeichenfolge "__main__"
gesetzt. Auf diese Weise können Sie testen, ob Ihr Skript direkt ausgeführt oder von etwas anderem importiert wird
if __== "__main__":
...
Wenn Ihr Skript in ein anderes Modul importiert wird, werden die verschiedenen Funktions- und Klassendefinitionen importiert und der Code der obersten Ebene wird ausgeführt, der Code im then-Body der if
-Klausel wird jedoch nicht abgerufen ausführen, da die Bedingung nicht erfüllt ist. Betrachten Sie als grundlegendes Beispiel die folgenden zwei Skripte:
# 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")
Nun, wenn Sie den Interpreter als aufrufen
python one.py
Die Ausgabe wird sein
top-level in one.py
one.py is being run directly
Wenn Sie stattdessen two.py
ausführen:
python two.py
Du kriegst
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
Wenn also das Modul one
geladen wird, ist sein __name__
gleich "one"
anstelle von "__main__"
.
Die einfachste Erklärung für die Variable __name__
(imho) lautet wie folgt:
Erstellen Sie die folgenden Dateien.
# a.py
import b
und
# b.py
print "Hello World from %s!" % __name__
if __== '__main__':
print "Hello World again from %s!" % __name__
Wenn Sie sie ausführen, erhalten Sie folgende Ausgabe:
$ python a.py
Hello World from b!
Wie Sie sehen, setzt Python beim Importieren eines Moduls globals()['__name__']
in diesem Modul auf den Namen des Moduls. Außerdem wird beim Import der gesamte Code im Modul ausgeführt. Da die Anweisung if
zu False
ausgewertet wird, wird dieser Teil nicht ausgeführt.
$ python b.py
Hello World from __main__!
Hello World again from __main__!
Wie Sie sehen, setzt Python beim Ausführen einer Datei globals()['__name__']
in dieser Datei auf "__main__"
. Dieses Mal wird die Anweisung if
zu True
ausgewertet und ausgeführt.
Was macht der
if __== "__main__":
?
Um die Grundlagen zu skizzieren:
Die globale Variable __name__
im Modul, das der Einstiegspunkt für Ihr Programm ist, lautet '__main__'
. Ansonsten ist es der Name, unter dem Sie das Modul importieren.
Daher wird Code unter dem Block if
nur ausgeführt, wenn das Modul der Einstiegspunkt für Ihr Programm ist.
Dadurch kann der Code im Modul von anderen Modulen importiert werden, ohne dass der unten stehende Codeblock beim Import ausgeführt wird.
Warum brauchen wir das?
Angenommen, Sie schreiben ein Python -Skript, das als Modul verwendet werden soll:
def do_important():
"""This function does something very important"""
Sie können das Modul testen, indem Sie den folgenden Funktionsaufruf unten einfügen:
do_important()
und starten Sie es (an einer Eingabeaufforderung) mit etwas wie:
~$ python important.py
Wenn Sie das Modul jedoch in ein anderes Skript importieren möchten:
import important
Beim Import wird die Funktion do_important
aufgerufen, sodass Sie wahrscheinlich Ihren Funktionsaufruf do_important()
unten auskommentieren würden.
# do_important() # I must remember to uncomment to execute this!
Und dann müssen Sie sich merken, ob Sie Ihren Testfunktionsaufruf auskommentiert haben oder nicht. Und diese zusätzliche Komplexität würde bedeuten, dass Sie es wahrscheinlich vergessen, was Ihren Entwicklungsprozess schwieriger macht.
Die Variable __name__
zeigt auf den Namespace, in dem sich der Interpreter Python gerade befindet.
In einem importierten Modul ist es der Name dieses Moduls.
Innerhalb des primären Moduls (oder einer interaktiven Sitzung Python, d. H. Read, Eval, Print Loop oder REPL des Interpreters) führen Sie jedoch alles von seinem "__main__"
aus.
Wenn Sie also vor dem Ausführen Folgendes überprüfen:
if __== "__main__":
do_important()
In diesem Fall wird der Code nur ausgeführt, wenn Sie ihn als primäres Modul ausführen (oder absichtlich von einem anderen Skript aus aufrufen).
Es gibt jedoch eine pythonische Möglichkeit, dies zu verbessern.
Was ist, wenn wir diesen Geschäftsprozess von außerhalb des Moduls ausführen möchten?
Wenn wir den Code, den wir ausüben möchten, während wir entwickeln und testen, in eine Funktion wie diese einfügen und dann sofort nach dem folgenden Schritt unsere Überprüfung auf '__main__'
durchführen:
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()
Wir haben jetzt eine letzte Funktion für das Ende unseres Moduls, die ausgeführt wird, wenn wir das Modul als primäres Modul ausführen.
Das Modul und seine Funktionen und Klassen können in andere Skripten importiert werden, ohne dass die Funktion main
ausgeführt wird. Das Modul (und seine Funktionen und Klassen) kann auch aufgerufen werden, wenn es von einem anderen '__main__'
-Modul ausgeführt wird. dh.
import important
important.main()
Diese Redewendung finden Sie auch in der Dokumentation zu Python in einer Erläuterung des Moduls __main__
. In diesem Text heißt es:
Dieses Modul stellt den (ansonsten anonymen) Bereich dar, in dem das Hauptprogramm des Interpreters ausgeführt wird - Befehle, die entweder von der Standardeingabe, einer Skriptdatei oder einer interaktiven Eingabeaufforderung gelesen werden. In dieser Umgebung wird durch die idiomatische Zeilengruppe "Bedingtes Skript" ein Skript ausgeführt:
if __== '__main__': main()
if __== "__main__"
ist der Teil, der ausgeführt wird, wenn das Skript über die Befehlszeile mit einem Befehl wie python myscript.py
ausgeführt wird.
Was macht
if __== "__main__":
?
__name__
ist eine globale Variable (in Python bedeutet global tatsächlich auf der Modulebene ), die in allen Namespaces vorhanden ist. Dies ist normalerweise der Name des Moduls (als str
-Typ).
Als einziger Sonderfall gilt jedoch für jeden Python -Prozess, den Sie ausführen, wie in mycode.py:
python mycode.py
dem ansonsten anonymen globalen Namespace wird der Wert von '__main__'
seinem __name__
zugewiesen.
Also, einschließlich die letzten Zeilen
if __== '__main__':
main()
bewirkt, dass die eindeutig definierte main
-Funktion Ihres Skripts ausgeführt wird.
Ein weiterer Vorteil der Verwendung dieses Konstrukts: Sie können Ihren Code auch als Modul in ein anderes Skript importieren und dann die Hauptfunktion ausführen, wenn Ihr Programm entscheidet:
import mycode
# ... any amount of other code
mycode.main()
Es gibt hier viele verschiedene Einstellungen zur Mechanik des fraglichen Codes, dem "Wie", aber für mich ergab nichts davon einen Sinn, bis ich das "Warum" verstand. Dies sollte insbesondere für neue Programmierer hilfreich sein.
Nimm die Datei "ab.py":
def a():
print('A function in ab file');
a()
Und eine zweite Datei "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()
Was macht dieser Code eigentlich?
Wenn Sie xy.py
ausführen, import ab
. Die import-Anweisung führt das Modul sofort beim Import aus, sodass die Operationen von ab
vor den übrigen Operationen von xy
ausgeführt werden. Wenn Sie mit ab
fertig sind, fahren Sie mit xy
fort.
Der Interpreter verfolgt, welche Skripte mit __name__
ausgeführt werden. Wenn Sie ein Skript ausführen - egal wie Sie es genannt haben -, nennt der Interpreter es "__main__"
und macht es zum Master- oder 'Home'-Skript, zu dem nach dem Ausführen eines externen Skripts zurückgekehrt wird.
Jedem anderen Skript, das von diesem "__main__"
Skript aufgerufen wird, wird sein Dateiname als sein __name__
zugewiesen (z. B. __== "ab.py"
). Daher ist die Zeile if __== "__main__":
der Test des Interpreters, um festzustellen, ob das 'Home'-Skript, das ursprünglich ausgeführt wurde, interpretiert/analysiert wird, oder ob es vorübergehend in ein anderes (externes) Skript eingesehen wird. Dies gibt dem Programmierer die Flexibilität, das Skript anders zu verhalten, wenn es direkt ausgeführt oder extern aufgerufen wird.
Lassen Sie uns den obigen Code durchgehen, um zu verstehen, was passiert, und uns zunächst auf die nicht eingerückten Zeilen und die Reihenfolge konzentrieren, in der sie in den Skripten erscheinen. Denken Sie daran, dass Funktions- oder def
-Bausteine nichts von sich aus tun, bis sie aufgerufen werden. Was der Dolmetscher sagen könnte, wenn er vor sich hin murmelte:
"__main__"
in der Variablen __name__
.__== "ab.py"
.a()
; Das habe ich gerade gelernt. Ausdruck ' Eine Funktion in einer Datei '."__main__"
!x()
; ok, drucke ' peripherie aufgabe: könnte in anderen projekten nützlich sein '.if
Anweisung. Nun, die Bedingung wurde erfüllt (die Variable __name__
wurde auf "__main__"
gesetzt), also werde ich die Funktion main()
aufrufen und die Hauptfunktion ' ausgeben : hier ist die Aktion '.Die beiden unteren Zeilen bedeuten: "Wenn dies das "__main__"
- oder 'home'-Skript ist, führen Sie die Funktion main()
aus." Aus diesem Grund wird oben ein Block def main():
angezeigt, der den Hauptfluss der Skriptfunktionalität enthält.
Warum dies implementieren?
Erinnern Sie sich, was ich zuvor über Importanweisungen gesagt habe? Wenn Sie ein Modul importieren, wird es nicht nur "erkannt" und auf weitere Anweisungen gewartet, sondern es werden alle ausführbaren Operationen ausgeführt, die im Skript enthalten sind. Wenn Sie also das Fleisch Ihres Skripts in die Funktion main()
verschieben, wird es effektiv in Quarantäne gestellt und isoliert, sodass es nicht sofort ausgeführt wird, wenn es von einem anderen Skript importiert wird.
Auch hier wird es Ausnahmen geben, aber es ist üblich, dass main()
normalerweise nicht extern aufgerufen wird. Sie fragen sich vielleicht noch etwas: Wenn wir nicht main()
aufrufen, warum rufen wir dann überhaupt das Skript auf? Dies liegt daran, dass viele Benutzer ihre Skripts mit eigenständigen Funktionen strukturieren, die unabhängig vom Rest des Codes in der Datei ausgeführt werden. Sie werden dann später an einer anderen Stelle im Hauptteil des Skripts aufgerufen. Was mich dazu bringt:
Aber der Code funktioniert ohne
Ja, das ist richtig. Diese separaten Funktionen können von einem Inline-Skript aufgerufen werden, das nicht in einer main()
-Funktion enthalten ist. Wenn Sie es gewohnt sind (wie ich es in meinen frühen Programmierphasen bin), Inline-Skripte zu erstellen, die genau das tun, was Sie benötigen, und Sie versuchen, es erneut herauszufinden, wenn Sie diese Operation jemals wieder benötigen. Nun, Sie sind nicht an diese Art der internen Struktur Ihres Codes gewöhnt, da die Erstellung komplizierter und das Lesen nicht so intuitiv ist.
Aber das ist ein Skript, dessen Funktionen wahrscheinlich nicht extern aufgerufen werden können, da es sonst sofort anfängt, Variablen zu berechnen und zuzuweisen. Und wenn Sie versuchen, eine Funktion wiederzuverwenden, hängt Ihr neues Skript wahrscheinlich eng genug mit dem alten Skript zusammen, sodass es zu Konflikten mit Variablen kommt.
Wenn Sie unabhängige Funktionen aufteilen, können Sie Ihre vorherigen Arbeiten wiederverwenden, indem Sie sie in einem anderen Skript aufrufen. Beispielsweise könnte "example.py" "xy.py" importieren und x()
aufrufen, wobei die 'x'-Funktion von "xy.py" verwendet wird. (Möglicherweise wird das dritte Wort einer bestimmten Textzeichenfolge in Großbuchstaben geschrieben, ein NumPy-Array aus einer Liste von Zahlen erstellt und diese quadriert oder eine 3D-Oberfläche entfernt. Die Möglichkeiten sind unbegrenzt.)
(Abgesehen davon enthält diese Frage eine Antwort von @kindall, die mir schließlich geholfen hat zu verstehen - das Warum, nicht das Wie. Leider wurde sie als Duplikat von diese markiert =, was ich für einen Fehler halte.)
Wenn es bestimmte Anweisungen in unserem Modul gibt (M.py
), die ausgeführt werden sollen, wenn sie als main ausgeführt werden (nicht importiert), können wir diese Anweisungen (Testfälle, print-Anweisungen) unter dieses if
Block.
Standardmäßig (wenn das Modul als Hauptmodul ausgeführt wird und nicht importiert wird) ist die Variable __name__
auf "__main__"
gesetzt, und wenn sie importiert wird, erhält die Variable __name__
meist einen anderen Wert wahrscheinlich der Name des Moduls ('M'
). Dies ist hilfreich, wenn Sie verschiedene Varianten eines Moduls zusammen ausführen und deren spezifische Eingabe- und Ausgabeanweisungen sowie Testfälle trennen möchten.
Kurz gesagt Verwenden Sie diesen Block 'if __== "main"
', um zu verhindern, dass (bestimmter) Code ausgeführt wird, wenn das Modul importiert wird.
Einfach ausgedrückt ist __name__
eine Variable, die für jedes Skript definiert ist und definiert, ob das Skript als Hauptmodul oder als importiertes Modul ausgeführt wird.
Also, wenn wir zwei Skripte haben;
#script1.py
print "Script 1's name: {}".format(__name__)
und
#script2.py
import script1
print "Script 2's name: {}".format(__name__)
Die Ausgabe von script1 lautet
Script 1's name: __main__
Und die Ausgabe von script2 ist:
Script1's name is script1
Script 2's name: __main__
Wie Sie sehen können, gibt __name__
an, welcher Code das Hauptmodul ist. Das ist großartig, weil Sie einfach Code schreiben können und sich nicht um strukturelle Probleme wie in C/C++ kümmern müssen. Wenn eine Datei keine Hauptfunktion implementiert, kann sie nicht als ausführbare Datei kompiliert werden, und wenn ja, Es kann dann nicht als Bibliothek verwendet werden.
Angenommen, Sie schreiben ein Python -Skript, das etwas Großartiges leistet, und Sie implementieren eine Fülle von Funktionen, die für andere Zwecke nützlich sind. Wenn ich sie verwenden möchte, kann ich einfach Ihr Skript importieren und sie verwenden, ohne Ihr Programm auszuführen (vorausgesetzt, Ihr Code wird nur im Kontext if __== "__main__":
ausgeführt). In C/C++ müssten Sie diese Teile in ein separates Modul aufteilen, das dann die Datei enthält. Stellen Sie sich die Situation unten vor.
Die Pfeile sind Importlinks. Für drei Module, die jeweils versuchen, den Code des vorherigen Moduls einzuschließen, gibt es sechs Dateien (neun, einschließlich der Implementierungsdateien) und fünf Links. Dies macht es schwierig, anderen Code in ein C-Projekt aufzunehmen, es sei denn, er ist speziell als Bibliothek kompiliert. Stellen Sie es sich jetzt für Python vor:
Sie schreiben ein Modul, und wenn jemand Ihren Code verwenden möchte, importiert er es einfach und die Variable __name__
kann dazu beitragen, den ausführbaren Teil des Programms vom Bibliotheksteil zu trennen.
Sehen wir uns die Antwort abstrakter an:
Angenommen, wir haben diesen Code in x.py:
...
<Block A>
if __== '__main__':
<Block B>
...
Die Blöcke A und B werden ausgeführt, wenn "x.py" ausgeführt wird.
Aber nur Block A (und nicht B) wird ausgeführt, wenn wir ein anderes Modul ausführen, z. B. "y.py", in das xy importiert und der Code von dort ausgeführt wird (wie bei einer Funktion in "x.py") angerufen von y.py).
Wenn Sie Python interaktiv ausführen, wird der lokalen __name__
-Variable der Wert __main__
zugewiesen. Wenn Sie ein Python -Modul über die Befehlszeile ausführen, anstatt es in ein anderes Modul zu importieren, wird seinem __name__
-Attribut anstelle des tatsächlichen Namens der Wert __main__
zugewiesen des Moduls. Auf diese Weise können Module anhand ihres eigenen __name__
-Werts selbst bestimmen, wie sie verwendet werden, ob als Unterstützung für ein anderes Programm oder als Hauptanwendung, die über die Befehlszeile ausgeführt wird. Daher ist die folgende Redewendung in Python -Modulen durchaus üblich:
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.
Erwägen:
if __== "__main__":
main()
Es wird geprüft, ob das __name__
-Attribut des Python -Skripts "__main__"
ist. Mit anderen Worten, wenn das Programm selbst ausgeführt wird, lautet das Attribut __main__
, sodass das Programm ausgeführt wird (in diesem Fall die Funktion main()
).
Wenn Ihr Python -Skript jedoch von einem Modul verwendet wird, wird jeder Code außerhalb der if
-Anweisung ausgeführt, sodass if \__== "\__main__"
nur verwendet wird, um zu überprüfen, ob das Programm als verwendet wird ein Modul oder nicht, und entscheidet daher, ob der Code ausgeführt werden soll.
Bevor Sie etwas über if __== '__main__'
erklären, ist es wichtig zu verstehen, was __name__
ist und was es tut.
Was ist
__name__
?
__name__
ist ein DunderAlias - kann als globale Variable betrachtet werden (über Module zugänglich) und funktioniert ähnlich wie global
.
Es ist eine Zeichenfolge (global, wie oben erwähnt), wie durch type(__name__)
angegeben (was <class 'str'>
ergibt), und ein eingebauter Standard für Python und Python 2) Versionen.
Wobei:
Es kann nicht nur in Skripten verwendet werden, sondern ist auch sowohl im Interpreter als auch in den Modulen/Paketen zu finden.
Dolmetscher:
>>> print(__name__)
__main__
>>>
Skript:
test_file.py :
print(__name__)
Ergebnis __main__
Modul oder Paket:
somefile.py:
def somefunction():
print(__name__)
test_file.py:
import somefile
somefile.somefunction()
Ergebnis somefile
Beachten Sie, dass __name__
bei Verwendung in einem Paket oder Modul den Namen der Datei annimmt. Der Pfad des eigentlichen Modul- oder Paketpfads ist nicht angegeben, hat jedoch einen eigenen DunderAlias __file__
, der dies ermöglicht.
Sie sollten sehen, dass __name__
, wo es sich um die Hauptdatei (oder das Hauptprogramm) handelt, immer __main__
zurückgibt und ob es sich um ein Modul handelt/Paket oder alles, was mit einem anderen Python Skript ausgeführt wird, gibt den Namen der Datei zurück, von der es stammt.
Übung:
Eine Variable zu sein bedeutet, dass ihr Wert can überschrieben wird ("can" bedeutet nicht "should"), und das Überschreiben des Werts von __name__
führt zu mangelnder Lesbarkeit . Mach es also aus irgendeinem Grund nicht. Wenn Sie eine Variable benötigen, definieren Sie eine neue Variable.
Es wird immer angenommen, dass der Wert von __name__
__main__
oder der Name der Datei ist. Erneutes Ändern dieses Standardwerts führt zu größerer Verwirrung darüber, dass er sich als nützlich erweist, und später zu Problemen.
Beispiel:
>>> __= 'Horrify' # Change default from __main__
>>> if __== 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>
Es wird allgemein als bewährte Methode angesehen, den if __== '__main__'
in Skripten aufzunehmen.
Um nun
if __== '__main__'
zu beantworten:
Jetzt wissen wir, wie sich __name__
verhält:
Ein if
ist eine Flusssteuerungsanweisung, die den Codeblock enthält, der ausgeführt wird, wenn der angegebene Wert wahr ist. Wir haben gesehen, dass __name__
entweder __main__
oder den Dateinamen annehmen kann, aus dem es importiert wurde.
Das heißt, wenn __name__
gleich __main__
ist, muss die Datei die Hauptdatei sein und muss tatsächlich ausgeführt werden (oder es ist der Interpreter), kein Modul oder Paket, das in das Skript importiert wurde.
Wenn __name__
tatsächlich den Wert von __main__
annimmt, wird alles ausgeführt, was sich in diesem Codeblock befindet.
Dies sagt uns, dass diese Bedingung ausgeführt werden muss, wenn die ausgeführte Datei die Hauptdatei ist (oder Sie direkt vom Interpreter ausführen). Wenn es ein Paket ist, sollte es nicht sein und der Wert wird nicht __main__
sein.
Module:
__name__
kann auch in Modulen verwendet werden, um den Namen eines Moduls zu definieren
Varianten:
Es ist auch möglich, mit __name__
andere, weniger gebräuchliche, aber nützliche Dinge zu tun. Einige werde ich hier zeigen:
Nur ausführen, wenn die Datei ein Modul oder ein Paket ist:
if __!= '__main__':
# Do some useful things
Ausführen einer Bedingung, wenn die Datei die Hauptbedingung ist, und einer anderen, wenn dies nicht der Fall ist:
if __== '__main__':
# Execute something
else:
# Do some useful things
Sie können es auch verwenden, um ausführbare Hilfefunktionen/Dienstprogramme für Pakete und Module bereitzustellen, ohne Bibliotheken zu verwenden.
Außerdem können Module über die Befehlszeile als Hauptskripte ausgeführt werden, was ebenfalls sehr nützlich sein kann.
Ich denke, es ist am besten, die Antwort gründlich und in einfachen Worten zu brechen:
__name__
: Jedes Modul in Python hat ein spezielles Attribut namens __name__
. Es ist eine integrierte Variable, die den Namen des Moduls zurückgibt.
__main__
: Wie andere Programmiersprachen hat auch Python einen Ausführungseinstiegspunkt, d. H. Main. '__main__'
ist der Name des Bereichs, in dem Code der obersten Ebene ausgeführt wird. Grundsätzlich haben Sie zwei Möglichkeiten, ein Python -Modul zu verwenden: Führen Sie es direkt als Skript aus oder importieren Sie es. Wenn ein Modul als Skript ausgeführt wird, wird sein __name__
auf __main__
gesetzt.
Daher wird der Wert des Attributs __name__
auf __main__
gesetzt, wenn das Modul als Hauptprogramm ausgeführt wird. Andernfalls wird der Wert von __name__
so festgelegt, dass er den Namen des Moduls enthält.
Dies ist eine Besonderheit, wenn eine Python -Datei über die Befehlszeile aufgerufen wird. Dies wird normalerweise verwendet, um eine "main ()" - Funktion aufzurufen oder anderen geeigneten Startcode auszuführen, wie zum Beispiel die Behandlung von Befehlszeilenargumenten.
Es könnte auf verschiedene Arten geschrieben werden. Ein anderer ist:
def some_function_for_instance_main():
dosomething()
__== '__main__' and some_function_for_instance_main()
Ich sage nicht, dass Sie dies im Produktionscode verwenden sollten, aber es soll veranschaulichen, dass if __== '__main__'
nichts "Magisches" ist. Es ist eine gute Konvention zum Aufrufen einer Hauptfunktion in Python -Dateien.
Es gibt eine Reihe von Variablen, die das System (Python-Interpreter) für Quelldateien (Module) bereitstellt. Sie können ihre Werte jederzeit abrufen. Konzentrieren Sie sich also auf die Variable _ NAME _/attribute:
Wenn Python eine Quellcodedatei lädt, wird der gesamte darin enthaltene Code ausgeführt. (Beachten Sie, dass nicht alle in der Datei definierten Methoden und Funktionen aufgerufen, sondern definiert werden.)
Bevor der Interpreter die Quellcodedatei ausführt, definiert er einige spezielle Variablen für diese Datei. _ NAME _ ist eine dieser speziellen Variablen, die Python automatisch für jede Quellcodedatei definiert.
Wenn Python diese Quellcodedatei als Hauptprogramm lädt (dh die Datei, die Sie ausführen), wird die spezielle _ NAME _ -Variable für diese Datei auf einen Wert gesetzt "__main __".
Wenn dies von einem anderen Modul importiert wird, wird _ NAME _ auf den Namen dieses Moduls gesetzt.
Also, in Ihrem Beispiel zum Teil:
if __== "__main__":
lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
bedeutet, dass der Codeblock:
lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
wird nur ausgeführt, wenn Sie das Modul direkt ausführen; Der Codeblock wird nicht ausgeführt, wenn ein anderes Modul ihn aufruft/importiert, da der Wert von _ NAME _ in dieser bestimmten Instanz nicht gleich "main" ist.
Hoffe das hilft aus.
if __== "__main__":
ist im Grunde die Skriptumgebung der obersten Ebene und gibt den Interpreter an, der ("Ich habe die höchste Priorität, die zuerst ausgeführt werden muss").
'__main__'
ist der Name des Bereichs, in dem Code der obersten Ebene ausgeführt wird. Das __name__
eines Moduls wird auf '__main__'
gesetzt, wenn es von der Standardeingabe, einem Skript oder einer interaktiven Eingabeaufforderung gelesen wird.
if __== "__main__":
# Execute only if run as a script
main()
Der Grund für
if __== "__main__":
main()
ist in erster Linie, um die Importsperre Probleme zu vermeiden, die durch Code direkt importieren lassen entstehen würden. Sie möchten, dass main()
ausgeführt wird, wenn Ihre Datei direkt aufgerufen wurde (das ist der Fall __== "__main__"
), aber wenn Ihr Code importiert wurde, muss der Importeur Ihren Code vom eigentlichen Hauptmodul eingeben, um Probleme mit der Importsperre zu vermeiden .
Ein Nebeneffekt ist, dass Sie sich automatisch bei einer Methode anmelden, die mehrere Einstiegspunkte unterstützt. Sie können Ihr Programm mit main()
als Einstiegspunkt ausführen , aber Sie müssen nicht . Während setup.py
main()
erwartet, verwenden andere Tools alternative Einstiegspunkte. Um Ihre Datei beispielsweise als gunicorn
-Prozess auszuführen, definieren Sie eine app()
-Funktion anstelle einer main()
. Genau wie bei setup.py
importiert gunicorn
Ihren Code, sodass Sie nicht möchten, dass er während des Imports etwas tut (aufgrund des Importsperrproblems).
Ich habe so viel in den Antworten auf dieser Seite gelesen. Ich würde sagen, wenn Sie die Sache kennen, werden Sie diese Antworten sicher verstehen, sonst sind Sie immer noch verwirrt.
Um kurz zu sein, müssen Sie einige Punkte kennen:
import a
Aktion führt tatsächlich alles aus, was in "a" ausgeführt werden kann
Aufgrund von Punkt 1 möchten Sie möglicherweise nicht, dass beim Importieren alles in "a" ausgeführt wird
Um das Problem in Punkt 2 zu lösen, können Sie mit python eine Bedingungsprüfung durchführen
__name__
ist eine implizite Variable in allen .py-Modulen. Beim Import von a.py wird der Wert von __name__
eines.py-Moduls auf den Dateinamen "a" gesetzt. Wenn a.py direkt mit "python a.py" ausgeführt wird, was bedeutet, dass a.py der Einstiegspunkt ist, wird der Wert von __name__
eines.py-Moduls auf eine Zeichenfolge __main__
gesetzt.
Wissen Sie anhand des Mechanismus, wie python die Variable __name__
für jedes Modul festlegt, wie Sie Punkt 3 erreichen? Die Antwort ist ziemlich einfach, oder? Setzen Sie eine if-Bedingung: if __== "__main__": ...
; Sie können sogar wenn __== "a"
abhängig von Ihrem Funktionsbedarf setzen
Die wichtige Sache, die python speziell ist, ist Punkt 4! Der Rest ist nur Grundlogik.
Erwägen:
print __name__
Die Ausgabe für das Obige ist __main__
.
if __== "__main__":
print "direct method"
Die obige Aussage ist wahr und gibt "direkte Methode" aus. Angenommen, diese Klasse wird in einer anderen Klasse importiert und nicht gedruckt "direkte Methode", da beim Importieren __equal to "first model name"
gesetzt wird.
Sie können die Datei als Skript sowie als importierbares Modul verwenden. ).
fibo.py (ein Modul mit dem Namen 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]))
Diese Antwort richtet sich an Java Programmierer, die Python lernen. Jede Java -Datei enthält normalerweise eine öffentliche Klasse. Sie können diese Klasse auf zwei Arten verwenden:
Rufen Sie die Klasse aus anderen Dateien auf. Sie müssen es nur in das aufrufende Programm importieren.
Führen Sie die Klasse zu Testzwecken eigenständig aus.
Im letzteren Fall sollte die Klasse eine öffentliche static void main () -Methode enthalten. In Python wird dieser Zweck durch das global definierte Label '__main__'
erfüllt.
Wenn diese .py-Datei von anderen .py-Dateien importiert wird, wird der Code unter "der if-Anweisung" nicht ausgeführt.
Wenn diese .py von python this_py.py
unter Shell ausgeführt oder in Windows doppelt angeklickt werden. Der Code unter "der if-Anweisung" wird ausgeführt.
Es wird normalerweise zum Testen geschrieben.
Erstellen Sie eine Datei a.py :
print(__name__) # It will print out __main__
__name__
ist immer gleich __main__
, wenn diese Datei direkt ausgeführt wird und dies die Hauptdatei ist.
Erstellen Sie eine weitere Datei b.py im selben Verzeichnis:
import a # Prints a
Starte es. Es wird ein ausgegeben, d. H. Der Name der Datei, die importiert wird .
Um also zwei verschiedene Verhaltensweisen derselben Datei zu zeigen, ist dies ein häufig verwendeter Trick:
# Code to be run when imported into another python file
if __== '__main__':
# Code to be run only when run directly
Wir sehen, ob __== '__main__':
ziemlich oft.
Es wird geprüft, ob ein Modul importiert wird oder nicht.
Mit anderen Worten, der Code innerhalb des Blocks if
wird nur ausgeführt, wenn der Code direkt ausgeführt wird. Hier bedeutet directly
not imported
.
Sehen wir uns an, wie es mit einem einfachen Code funktioniert, der den Namen des Moduls ausgibt:
# test.py
def test():
print('test module name=%s' %(__name__))
if __== '__main__':
print('call test()')
test()
Wenn wir den Code direkt über python test.py
ausführen, lautet der Modulname __main__
:
call test()
test module name=__main__
Alle Antworten haben die Funktionalität ziemlich genau erklärt. Ich werde jedoch ein Beispiel für seine Verwendung nennen, das dazu beitragen könnte, das Konzept weiter zu verdeutlichen.
Angenommen, Sie haben zwei Python Dateien, a.py und b.py. Nun importiert a.py b.py. Wir führen die a.py-Datei aus, in der zuerst der Code "import b.py" ausgeführt wird. Bevor der Rest des a.py-Codes ausgeführt wird, muss der Code in der Datei b.py vollständig ausgeführt werden.
Im b.py-Code gibt es einen Code, der ausschließlich für die Datei b.py bestimmt ist, und wir möchten, dass keine andere Datei (außer der b.py-Datei), die die b.py-Datei importiert hat, diese ausführt.
Das ist es also, was diese Codezeile überprüft. Wenn es sich um die Hauptdatei (d. H. B.py) handelt, die den Code ausführt, was in diesem Fall nicht der Fall ist (a.py ist die Hauptdatei, die ausgeführt wird), wird nur der Code ausgeführt.
Es ist einfach der Einstiegspunkt, um die Datei wie die Funktion main
in der Programmiersprache C auszuführen.
Jedes Modul in python hat ein Attribut, das name heißt. Der Wert des Attributs name ist 'main', wenn das Modul direkt ausgeführt wird. Ansonsten ist der Wert von name der Name des Moduls.
Kleines Beispiel, um es kurz zu erklären.
#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()
Wir können dies direkt als ausführen
python test.py
Ausgabe
Value of __is: __main__
Going to call hello_world
I am inside hello_world
Nehmen wir nun an, wir rufen das obige Skript von einem anderen Skript auf
#script external_calling.py
import test
print(test.Apple)
test.hello_world()
print(test.__name__)
Wenn Sie dies ausführen
python external_calling.py
Ausgabe
42
I am inside hello_world
test
Das obige erklärt sich von selbst, wenn Sie test aus einem anderen Skript aufrufen, wenn loop name in test.py nicht ausgeführt wird.
Wenn der Interpreter python ein bestimmtes Modul ausführt, hat die globale Variable __name__
den Wert "__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()
Wenn Sie dieses Skript ausführen, wird Sie können mich sehen gedruckt
a
Wenn Sie diese Datei importieren, sagen Sie A zu Datei B und führen Sie die Datei B aus, dann wird if __== "__main__"
in Datei A falsch, so dass es gedruckt wird Sie können mich nicht sehen
b