python if '__main__' - Was passiert, wenn __name__ == "__main__":




13 Answers

Wenn Ihr Skript ausgeführt wird, indem Sie es als Befehl an den Python-Interpreter übergeben,

python myscript.py

Der gesamte Code, der sich auf Einrückungsebene 0 befindet, wird ausgeführt. Definierte Funktionen und Klassen sind gut definiert, aber der Code wird nicht ausgeführt. Im Gegensatz zu anderen Sprachen gibt es keine main() Funktion, die automatisch ausgeführt wird - die main() Funktion 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 auswertet. Wenn jedoch ein Modul direkt ausgeführt wird (wie oben in myscript.py ), __name__ stattdessen __name__ auf die Zeichenfolge "__main__" . So können Sie testen, ob Ihr Skript direkt ausgeführt wird oder durch etwas anderes importiert wird

if __name__ == "__main__":
    ...

Wenn Ihr Skript in ein anderes Modul importiert wird, werden die verschiedenen Funktions- und Klassendefinitionen importiert und der Code der obersten Ebene ausgeführt. Der Code im Then-Body der if Klausel wird jedoch nicht als Bedingung ausgeführt ist nicht erfüllt. Als grundlegendes Beispiel betrachten Sie die folgenden zwei Skripts:

# 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")

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 :

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 das Modul one geladen wird, entspricht dessen __name__ "one" anstelle von "__main__" .

deutsch invalid syntax

Was macht das 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))



Was macht das if __name__ == "__main__":

Um die Grundlagen zu beschreiben:

  • Die globale Variable __name__ in dem Modul, das der Einstiegspunkt in Ihr Programm ist, lautet '__main__' . Ansonsten ist es der Name, unter dem Sie das Modul importieren.

  • Code unter dem if Block wird also nur ausgeführt, wenn das Modul der Einstiegspunkt in Ihr Programm ist.

  • Dadurch kann der Code im Modul von anderen Modulen importiert werden, ohne dass der Codeblock beim Import ausgeführt wird.

Warum brauchen wir das?

Entwickeln und Testen Ihres Codes

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 diesen Aufruf der Funktion unten hinzufügen:

do_important()

und ausführen (an einer Eingabeaufforderung) mit etwas wie:

~$ python important.py

Das Problem

Wenn Sie das Modul jedoch in ein anderes Skript importieren möchten:

import important

Beim Importieren wird die do_important Funktion aufgerufen, sodass Sie Ihren Funktionsaufruf do_important() am Ende wahrscheinlich do_important() .

# do_important() # I must remember to uncomment to execute this!

Und dann müssen Sie wissen, ob Sie den Aufruf der Testfunktion auskommentiert haben. Und diese zusätzliche Komplexität würde bedeuten, dass Sie wahrscheinlich vergessen werden, was Ihren Entwicklungsprozess schwieriger macht.

Ein besserer Weg

Die Variable __name__ zeigt auf den Namespace, wo sich der Python-Interpreter gerade befindet.

In einem importierten Modul ist dies der Name dieses Moduls.

Aber innerhalb des primären Moduls (oder einer interaktiven Python-Sitzung, z. B. Read, Eval, Print Loop oder REPL des Interpreters) führen Sie alles von seinem "__main__" .

Also, wenn Sie vor der Ausführung prüfen:

if __name__ == "__main__":
    do_important()

Mit den obigen Anweisungen wird Ihr Code nur ausgeführt, wenn Sie ihn als primäres Modul ausführen (oder absichtlich von einem anderen Skript aus aufrufen).

Ein noch besserer Weg

Es gibt jedoch einen pythonischen Weg, um dies zu verbessern.

Was ist, wenn wir diesen Geschäftsprozess außerhalb des Moduls ausführen möchten?

Wenn wir den Code einsetzen, den wir beim Entwickeln und Testen in einer Funktion wie dieser ausüben möchten, prüfen '__main__' sofort nach '__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()

Wir haben jetzt eine letzte Funktion für das Ende unseres Moduls, die ausgeführt wird, wenn wir das Modul als Primärmodul ausführen.

Dadurch können das Modul und seine Funktionen und Klassen in andere Skripts importiert werden, ohne dass die main wird. Außerdem können das Modul (und seine Funktionen und Klassen) aufgerufen werden, wenn es von einem anderen '__main__' Modul ausgeführt wird, dh

import important
important.main()

Diese Redewendung kann auch in der Python-Dokumentation in einer Erläuterung des __main__ Moduls gefunden werden. In diesem Text heißt es:

Dieses Modul stellt den (ansonsten anonymen) Umfang dar, in dem das Hauptprogramm des Interpreters ausgeführt wird - Befehle, die entweder aus der Standardeingabe, aus einer Skriptdatei oder aus einer interaktiven Eingabeaufforderung gelesen werden. In dieser Umgebung führt die idiomatic-Zeilengruppe "Bedingtes Skript" zur Ausführung eines Skripts:

if __name__ == '__main__':
    main()



Was passiert, if __name__ == "__main__":

__name__ ist eine globale Variable (in Python bedeutet global eigentlich auf Modulebene ), die in allen Namespaces vorhanden ist. Normalerweise ist dies der Name des Moduls (als str Typ).

Als einziger Sonderfall jedoch, egal in welchem ​​Python-Prozess Sie ausführen, wie in mycode.py:

python mycode.py

Dem ansonsten anonymen globalen Namespace wird der Wert '__main__' seinem __name__ .

So auch die letzten Zeilen

if __name__ == '__main__':
    main()
  • am Ende Ihres mycode.py-Skripts
  • Wenn es sich um das primäre Einstiegspunktmodul handelt, das von einem Python-Prozess ausgeführt wird,

führt dazu, dass die eindeutig definierte main Ihres Skripts ausgeführt wird.

Ein weiterer Vorteil der Verwendung dieses Konstrukts: Sie können Ihren Code auch als Modul in einem anderen Skript importieren und dann die Hauptfunktion ausführen, wenn Ihr Programm entscheidet:

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



Wenn es bestimmte Anweisungen in unserem Modul ( M.py ) gibt, die ausgeführt werden sollen, wenn es als main (nicht importiert) ausgeführt wird, können wir diese Anweisungen (Testfälle, print-Anweisungen) unter diesen if Block stellen.

Standardmäßig (wenn das Modul als Main ausgeführt wird, nicht importiert) ist die Variable __name__ auf "__main__" . Wenn sie importiert wird, erhält die Variable __name__ einen anderen Wert, höchstwahrscheinlich den Namen des Moduls ( 'M' ). Dies ist hilfreich, wenn Sie verschiedene Varianten eines Moduls zusammen ausführen und deren spezifische Eingabe- und Ausgabeanweisungen trennen, und auch, wenn Testfälle vorliegen.

Verwenden Sie diesen ' if __name__ == "main" "Block, um zu verhindern, dass (bestimmter) Code ausgeführt wird, wenn das Modul importiert wird.




Vereinfacht gesagt 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.

Wenn wir also 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 Skript1 wird ausgeführt

Script 1's name: __main__

Die Ausgabe von script2 lautet:

Script1's name is script1
Script 2's name: __main__

Wie Sie sehen, teilt uns __name__ mit, welcher Code das Hauptmodul ist. Das ist großartig, da Sie nur Code schreiben können und sich nicht um strukturelle Probleme wie in C / C ++ kümmern müssen. Wenn eine Datei keine 'main'-Funktion implementiert, kann sie nicht als ausführbare Datei kompiliert werden. es kann dann nicht als Bibliothek verwendet werden.

Angenommen, Sie schreiben ein Python-Skript, das etwas Großes bewirkt, und implementieren eine Bootload von Funktionen, die für andere Zwecke nützlich sind. Wenn ich sie verwenden möchte, kann ich Ihr Skript einfach importieren und verwenden, ohne Ihr Programm auszuführen ( if __name__ == "__main__": , Ihr Code wird nur innerhalb des if __name__ == "__main__": . 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 vorherigen Modulcode einzuschließen, gibt es sechs Dateien (neun, die Implementierungsdateien zählen) und fünf Verknüpfungen. Dies macht es schwierig, anderen Code in ein C-Projekt einzufügen, wenn er nicht speziell als Bibliothek kompiliert wird. Nun stell es dir für Python vor:

Sie schreiben ein Modul, und wenn jemand Ihren Code verwenden möchte, importieren Sie ihn einfach und die Variable __name__ kann dazu beitragen, den ausführbaren Teil des Programms vom Bibliotheksteil zu trennen.




Erwägen:

if __name__ == "__main__":
    main()

Es prüft, ob das __name__ Attribut des Python-Skripts "__main__" . Wenn also das Programm selbst ausgeführt wird, __main__ das Attribut __main__ . Das Programm wird also ausgeführt (in diesem Fall die Funktion main() ).

Wenn Ihr Python-Skript jedoch von einem Modul verwendet wird, wird jeglicher Code außerhalb der if Anweisung ausgeführt. if \__name__ == "\__main__" wird, wird nur if \__name__ == "\__main__" , ob das Programm als Modul verwendet wird oder nicht, und entscheidet daher, ob der Code ausgeführt wird.




Das System (Python-Interpreter) stellt eine Reihe von Variablen für Quelldateien (Module) bereit. Sie können ihre Werte jederzeit abrufen , also konzentrieren wir uns auf die Variable / das Attribut __name__ :

Wenn Python eine Quellcodedatei lädt, führt es den gesamten darin enthaltenen Code aus. (Beachten Sie, dass nicht alle in der Datei definierten Methoden und Funktionen aufgerufen werden, sondern sie definiert werden.)

Bevor der Interpreter die Quellcodedatei ausführt, definiert er jedoch 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 von Ihnen ausgeführte Datei), wird die spezielle Variable __name__ für diese Datei mit dem Wert "__main__" festgelegt .

Wenn dieses aus einem anderen Modul importiert wird, wird __name__ auf den Namen dieses Moduls gesetzt.

In deinem Beispiel also:

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))

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.




Dies ist ein Sonderfall, wenn eine Python-Datei von der Befehlszeile aus aufgerufen wird. Dies wird normalerweise verwendet, um eine "main ()" - Funktion aufzurufen oder einen anderen geeigneten Startcode auszuführen, wie zum Beispiel Befehlszeilenargumente, die zum Beispiel behandelt werden.

Es könnte auf verschiedene Arten geschrieben werden. Ein anderes ist:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

Ich sage nicht, dass Sie dies im Produktionscode verwenden sollten, aber es zeigt, dass es nichts "Magisches" gibt, if __name__ == '__main__' . Dies ist eine gute Konvention zum Aufrufen einer Hauptfunktion in Python-Dateien.




Der Grund für

if __name__ == "__main__":
    main()

dient in erster Linie dazu, die Probleme der Importsperre zu vermeiden, die sich aus dem direkten Import von Code ergeben würden. Sie möchten, dass main() ausgeführt wird, wenn Ihre Datei direkt aufgerufen wurde (dies ist der Fall __name__ == "__main__" ), aber wenn Ihr Code importiert wurde, muss der Importer Ihren Code vom echten Hauptmodul eingeben, um Probleme bei 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, müssen dies aber nicht . Während setup.py mit main() rechnet, verwenden andere Tools alternative Einstiegspunkte. Um Ihre Datei beispielsweise als gunicorn Prozess gunicorn , definieren Sie eine app() Funktion anstelle eines main() . Genau wie bei setup.py importiert gunicorn Ihren Code, sodass Sie nicht möchten, dass er während des Imports (aufgrund des Importsperrenproblems) irgendetwas tut.




Erwägen:

print __name__

Die Ausgabe für das obige ist __main__ .

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

Die obige Aussage ist wahr und gibt "direkte Methode" aus .Angenommen, diese Klasse wurde in eine andere Klasse importiert, es wird keine "direkte Methode" gedruckt, da sie beim Importieren gesetzt wird __name__ equal to "firstmodel name".




Wenn diese .py-Datei von anderen .py-Dateien importiert wird, wird der Code unter der "if-Anweisung" nicht ausgeführt.

Wenn diese .py-Datei von python this_py.pyShell ausgeführt wird oder in Windows doppelt geklickt wird. Der Code unter der "if-Anweisung" wird ausgeführt.

Es wird normalerweise zum Testen geschrieben.




Alle Antworten haben die Funktionalität ziemlich erklärt. Ich werde jedoch ein Beispiel für seine Verwendung geben, das helfen könnte, das Konzept weiter auszuräumen.

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 der Code "import b.py" zuerst 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 Code, der exklusiv für diese Datei b.py ist, und wir möchten keine andere Datei (außer b.py-Datei), die die b.py-Datei importiert hat, ausführen.

Das ist also, was diese Codezeile überprüft. Wenn es sich um die Hauptdatei (dh b.py) handelt, die den Code ausführt, was in diesem Fall nicht der Fall ist (a.py ist die Hauptdatei), wird nur der Code ausgeführt.




wenn name == ' main ':

Wir sehen es __name__ == '__main__':oft.

Es wird geprüft, ob ein Modul importiert wird oder nicht.

Mit anderen Worten, der Code innerhalb des ifBlocks wird nur ausgeführt, wenn der Code direkt ausgeführt wird. Hier directlybedeutet not imported.

Sehen wir uns an, was es mit einem einfachen Code tut, der den Namen des Moduls ausgibt:

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

Wenn wir den Code direkt über ausführen python test.py, lautet der Modulname __main__:

call test()
test module name=__main__



Related