7951 Stimmen

Was passiert, wenn __name__ == "__main__":?

Was bewirkt dies?

if __name__ == "__main__":
    print("Hello world!")

34 Stimmen

Nur fürs Protokoll - was ist " Haupt ": docs.python.org/3/reference/ und was ist " Name ": docs.python.org/3/reference/

113voto

Was bedeutet if __name__ == "__main__": tun?

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

Als einziger Sonderfall jedoch in jedem Python-Prozess, den Sie ausführen, wie in mycode.py:

python mycode.py

wird der ansonsten anonyme globale Namensraum mit dem Wert von '__main__' zu seinem __name__ .

Daher ist die Einbeziehung die letzten Zeilen

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

führt dazu, dass das eindeutig definierte Skript main Funktion auszuführen.

Ein weiterer Vorteil dieses Konstrukts: Sie können Ihren Code auch als Modul in ein anderes Skript importieren und dann die Hauptfunktion ausführen, wenn Ihr Programm dies wünscht:

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

97voto

joechoj Punkte 1249

Es gibt hier viele verschiedene Ansichten über die Mechanik des fraglichen Codes, das "Wie", aber für mich machte nichts davon Sinn, bis ich das "Warum" verstanden hatte. Dies sollte besonders für neue Programmierer hilfreich sein.

Nehmen Sie 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 __name__ == "__main__":
    main()

Was macht dieser Code eigentlich?

Wenn Sie Folgendes ausführen xy.py Sie import ab . Die Import-Anweisung führt das Modul sofort nach dem Import aus, also ab Operationen ausgeführt werden, bevor der Rest von xy 's. Sobald Sie mit ab geht es weiter mit xy .

Der Interpreter merkt sich, welche Skripte gerade laufen mit __name__ . Wenn Sie ein Skript ausführen - unabhängig davon, wie Sie es benannt haben - ruft der Interpreter es "__main__" Dadurch wird es zum Master- oder "Home"-Skript, zu dem nach der Ausführung eines externen Skripts zurückgekehrt wird.

Jedes andere Skript, das von diesem Skript aufgerufen wird "__main__" Skript wird sein Dateiname als sein __name__ (z.B., __name__ == "ab.py" ). Daher ist die Linie if __name__ == "__main__": ist der Test des Interpreters, um festzustellen, ob er das ursprünglich ausgeführte 'home'-Skript interpretiert/parst oder ob er vorübergehend in ein anderes (externes) Skript hineinschaut. Dies gibt dem Programmierer die Flexibilität, das Skript anders zu verhalten, wenn es direkt ausgeführt oder extern aufgerufen wird.

Gehen wir den obigen Code durch, um zu verstehen, was passiert, und konzentrieren wir uns zunächst auf die Zeilen ohne Einrückungen und die Reihenfolge, in der sie in den Skripten erscheinen. Denken Sie daran, dass die Funktion - oder def - Blöcke tun von sich aus nichts, bis sie aufgerufen werden. Was der Interpreter sagen könnte, wenn er zu sich selbst murmelt:

  • Öffnen Sie xy.py als 'home'-Datei; rufen Sie sie auf "__main__" im __name__ variabel.
  • Datei importieren und öffnen mit dem __name__ == "ab.py" .
  • Oh, eine Funktion. Das werde ich mir merken.
  • Ok, Funktion a() Das habe ich gerade gelernt. Drucken ' Eine Funktion in ab Datei '.
  • Ende der Datei; zurück zu "__main__" !
  • Oh, eine Funktion. Das werde ich mir merken.
  • Eine andere.
  • Funktion x() ; ok, Druck ' periphere Aufgabe: könnte für andere Projekte nützlich sein '.
  • Was ist das? Eine if Erklärung. Nun, die Bedingung ist erfüllt (die Variable __name__ wurde festgelegt auf "__main__" ), also werde ich die main() Funktion und drucken ' Hauptfunktion: Hier findet die Aktion statt '.

Die beiden unteren Zeilen bedeuten: "Wenn dies der "__main__" oder 'home'-Skript, führen Sie die Funktion main() ". Deshalb sehen Sie eine def main(): Block oben, der den Hauptfluss der Skriptfunktionalität enthält.

Warum sollte dies geschehen?

Erinnern Sie sich, was ich vorhin über Importanweisungen gesagt habe? Wenn Sie ein Modul importieren, wird es nicht nur "erkannt" und auf weitere Anweisungen gewartet, sondern es werden tatsächlich alle im Skript enthaltenen ausführbaren Operationen ausgeführt. Wenn Sie also den Kern Ihres Skripts in die main() stellt es unter Quarantäne und isoliert es, so dass es nicht sofort ausgeführt wird, wenn es von einem anderen Skript importiert wird.

Auch hier wird es Ausnahmen geben, aber die gängige Praxis ist, dass main() wird normalerweise nicht von außen aufgerufen. Sie fragen sich also vielleicht noch etwas: Wenn wir nicht main() Warum rufen wir das Skript dann überhaupt auf? Das liegt daran, dass viele Leute ihre Skripte mit eigenständigen Funktionen strukturieren, die so aufgebaut sind, dass sie unabhängig vom restlichen Code in der Datei ausgeführt werden. Sie werden dann später an einer anderen Stelle im Skriptkörper aufgerufen. Das bringt mich zu diesem Punkt:

Aber der Code funktioniert auch ohne ihn

Ja, das ist richtig. Diese separaten Funktionen kann von einem Inline-Skript aufgerufen werden, das nicht innerhalb einer main() Funktion. Wenn Sie es gewohnt sind (so wie ich in meinen frühen Lernphasen des Programmierens), Inline-Skripte zu erstellen, die genau das tun, was Sie brauchen, und Sie versuchen, es wieder herauszufinden, wenn Sie diese Operation jemals wieder brauchen ... nun, dann sind Sie diese Art der internen Struktur Ihres Codes nicht gewohnt, weil es komplizierter ist, ihn zu erstellen und er nicht so intuitiv zu lesen ist.

Aber das ist ein Skript, dessen Funktionen wahrscheinlich nicht von außen aufgerufen werden können, weil es sonst sofort mit der Berechnung und Zuweisung von Variablen beginnen würde. Und wenn Sie versuchen, eine Funktion wiederzuverwenden, ist Ihr neues Skript wahrscheinlich so eng mit dem alten verwandt, dass es zu Konflikten mit Variablen kommt.

Durch die Aufteilung unabhängiger Funktionen erhalten Sie die Möglichkeit, Ihre vorherige Arbeit wiederzuverwenden, indem Sie sie in einem anderen Skript aufrufen. Zum Beispiel könnte "example.py" "xy.py" importieren und Folgendes aufrufen x() und verwendet dabei die Funktion 'x' aus "xy.py". (Vielleicht geht es darum, das dritte Wort einer gegebenen Textkette groß zu schreiben; ein NumPy-Array aus einer Liste von Zahlen zu erstellen und diese zu quadrieren; oder eine 3D-Oberfläche zu dezentrieren. Die Möglichkeiten sind grenzenlos.)

(Nebenbei bemerkt, diese Frage enthält eine Antwort von @kindall, die mir endlich geholfen hat, zu verstehen - das Warum, nicht das Wie. Leider wurde sie als Duplikat markiert von diese was ich für einen Fehler halte.)

88voto

Giorgos Myrianthous Punkte 29317

Der Code unter if __name__ == '__main__': wird nur ausgeführt werden, wenn das Modul als Skript aufgerufen wird.

Als Beispiel sei das folgende Modul genannt my_test_module.py :

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

Erste Möglichkeit: Importieren Sie my_test_module.py in einem anderen Modul

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

Wenn Sie nun Folgendes aufrufen main.py :

python main.py

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

Beachten Sie, dass nur die oberste Ebene print() Anweisung in my_test_module ausgeführt wird.


Zweite Möglichkeit: Aufrufen von my_test_module.py als Skript

Wenn Sie nun my_test_module.py als Python-Skript, sowohl print() Anweisungen ausgeführt werden:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

Eine umfassendere Erklärung finden Sie unter Was bedeutet if __name__ == '__main__' tun in Python .

72voto

Nabeel Ahmed Punkte 16621

Wenn es in unserem Modul bestimmte Anweisungen gibt ( M.py ), die ausgeführt werden sollen, wenn sie als Hauptprogramm (nicht importiert) laufen, können wir diese Anweisungen (Testfälle, Druckanweisungen) unter diesem if Block.

Da standardmäßig (wenn das Modul als Main läuft, nicht importiert) die __name__ wird die Variable "__main__" und wann es importiert wird die __name__ erhält einen anderen Wert, höchstwahrscheinlich den Namen des Moduls ( 'M' ). Dies ist hilfreich, um verschiedene Varianten eines Moduls zusammen laufen zu lassen und ihre spezifischen Ein- und Ausgabeanweisungen zu trennen und auch wenn es Testfälle gibt.

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

0 Stimmen

+1 Manchmal ist es gut, nur einen kurzen Einzeiler wie in dieser Antwort zu erhalten: "Kurz gesagt, verwenden Sie dieses 'if Name \== "main" ' Block, um zu verhindern, dass (bestimmter) Code ausgeführt wird, wenn das Modul importiert wird.". Das ist sehr nützlich. Vielen Dank!

67voto

redbandit Punkte 2013

Einfach ausgedrückt, __name__ ist eine für jedes Skript definierte Variable, die angibt, 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 nach Ausführung von Skript1 lautet

Script 1's name: __main__

Und die Ausgabe nach der Ausführung von Skript2 ist:

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

Wie Sie sehen können, __name__ sagt uns, welcher Code das "Hauptmodul" ist. Das ist großartig, weil man einfach Code schreiben kann und sich keine Gedanken über strukturelle Probleme wie in C/C++ machen muss, wo eine Datei, die keine Hauptfunktion implementiert, nicht als ausführbare Datei kompiliert werden kann, und wenn doch, dann kann sie nicht als Bibliothek verwendet werden.

Angenommen, Sie schreiben ein Python-Skript, das etwas Großartiges leistet, und Sie implementieren eine ganze Reihe 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 (da Ihr Code nur innerhalb der if __name__ == "__main__": Kontext). In C/C++ hingegen müssten Sie diese Teile in ein separates Modul aufteilen, das dann die Datei enthält. Stellen Sie sich die folgende Situation vor;

Complicated importing in C

Die Pfeile sind Importlinks. Für drei Module, von denen jedes versucht, den Code des vorherigen Moduls einzubinden, gibt es sechs Dateien (neun, wenn man die Implementierungsdateien mitzählt) und fünf Links. Das macht es schwierig, anderen Code in ein C-Projekt einzubinden, es sei denn, er wird speziell als Bibliothek kompiliert. Nun stellen Sie sich das für Python vor:

Elegant importing in Python

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

2 Stimmen

Die C/C++-Darstellung ist falsch: 3 Mal der gleiche Unit-Name ( Datei1 ).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X