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


Was macht das? if __name__ == "__main__": machen?

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

4128
2018-01-07 04:11


Ursprung


Antworten:


Wenn der Python-Interpreter eine Quelldatei liest, führt er den gesamten darin enthaltenen Code aus.

Bevor der Code ausgeführt wird, werden einige spezielle Variablen definiert. Wenn der Python-Interpreter beispielsweise dieses Modul (die Quelldatei) als Hauptprogramm ausführt, wird das spezielle Programm festgelegt __name__ Variable, um einen Wert zu haben "__main__". Wenn diese Datei von einem anderen Modul importiert wird, __name__ wird auf den Modulnamen gesetzt.

Nehmen wir an, dass Ihr Skript als Hauptfunktion ausgeführt wird, z. Du hast so etwas gesagt

python threading_example.py

in der Befehlszeile. Nach dem Einrichten der speziellen Variablen wird der Befehl ausgeführt import Anweisung und laden Sie diese Module. Es wird dann das bewerten def Blockieren, Erstellen eines Funktionsobjekts und Erstellen einer Variablen namens myfunction das zeigt auf das Funktionsobjekt. Es wird dann lesen if Aussage und sehe das __name__ ist gleich "__main__", so wird der dort gezeigte Block ausgeführt.

Ein Grund dafür ist, dass Sie manchmal ein Modul schreiben (a .py Datei), wo es direkt ausgeführt werden kann. Alternativ kann es auch importiert und in einem anderen Modul verwendet werden. Wenn Sie die Hauptprüfung durchführen, können Sie diesen Code nur ausführen lassen, wenn Sie das Modul als Programm ausführen möchten und es nicht ausführen lassen, wenn jemand nur Ihr Modul importieren und Ihre Funktionen selbst aufrufen möchte.

Sehen diese Seite für einige zusätzliche Details.


4407
2018-01-07 04:26



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

python myscript.py

Der gesamte Code auf der Einrückungsebene 0 wird ausgeführt. Funktionen und Klassen, die definiert sind, sind gut definiert, aber keiner ihrer Code wird 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 in myscript.py oben), dann __name__ Stattdessen wird auf die Zeichenfolge festgelegt "__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 seine verschiedenen Funktions- und Klassendefinitionen importiert und sein Code der obersten Ebene wird ausgeführt, aber der Code im then-body des if Klausel oben wird nicht ausgeführt, da die Bedingung nicht erfüllt ist. Betrachten Sie als ein grundlegendes Beispiel 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")

Jetzt, 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 du läufst two.py stattdessen:

python two.py

Du erhältst

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

Also, wenn Modul one wird geladen, sein __name__ ist gleich "one" Anstatt von "__main__".


1403
2018-01-07 04:28



Die einfachste Erklärung für die __name__ Variable (imho) ist die folgende:

Erstellen Sie die folgenden Dateien.

# a.py
import b

und

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

Wenn Sie sie ausführen, erhalten Sie diese Ausgabe:

$ python a.py
Hello World from b!

Wie Sie sehen können, wird beim Import eines Moduls Python gesetzt globals()['__name__'] in diesem Modul zum Modulnamen.

$ python b.py
Hello World from __main__!
Hello World again from __main__!

Wie Sie sehen, wenn eine Datei ausgeführt wird, setzt Python globals()['__name__'] in dieser Datei zu "__main__".


560
2018-01-07 11:35



Was macht das? if __name__ == "__main__": machen?

Um die Grundlagen zu skizzieren:

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

  • Also, Code unter der if Der Block wird nur ausgeführt, wenn das Modul der Einstiegspunkt für Ihr Programm ist.

  • Es ermöglicht, dass der Code im Modul von anderen Modulen importiert werden kann, ohne dass der darunter liegende Codeblock beim Import ausgeführt wird.


Warum brauchen wir das?

Entwickeln und testen Sie Ihren Code

Angenommen, Sie schreiben ein Python-Skript, das als Modul verwendet werden soll:

def do_important():
    """This function does something very important"""

Sie könnte Testen Sie das Modul, indem Sie diesen Aufruf der Funktion unten hinzufügen:

do_important()

und es (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 Import, der do_important Funktion würde aufgerufen werden, also würden Sie wahrscheinlich Ihren Funktionsaufruf kommentieren, do_important(), unten.

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

Und dann müssen Sie sich daran erinnern, ob Sie Ihren Testfunktionsanruf auskommentiert haben oder nicht. Und diese zusätzliche Komplexität würde bedeuten, dass Sie wahrscheinlich vergessen werden, was Ihren Entwicklungsprozess schwieriger macht.

Ein besserer Weg

Das __name__ Variable verweist auf den Namespace, wo auch immer der Python-Interpreter gerade ist.

In einem importierten Modul ist dies der Name dieses Moduls.

Aber innerhalb des primären Moduls (oder einer interaktiven Python-Sitzung, d.h. dem Read, Eval, Print Loop oder REPL des Interpreters) läuft alles von seinem "__main__".

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

if __name__ == "__main__":
    do_important()

Mit dem oben genannten 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, 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 ausprobieren wollen, in einer Funktion wie dieser entwickeln und testen, dann machen wir unsere Prüfung '__main__' gleich nach:

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 nun eine letzte Funktion für das Ende unseres Moduls, das ausgeführt wird, wenn wir das Modul als primäres Modul ausführen.

Es ermöglicht das Importieren des Moduls und seiner Funktionen und Klassen in andere Skripts, ohne dass es ausgeführt werden muss main Funktion, und ermöglicht auch das Modul (und seine Funktionen und Klassen) aufgerufen werden, wenn von einem anderen ausgeführt wird '__main__' Modul, d.h.

import important
important.main()

Dieses Idiom finden Sie auch in der Python - Dokumentation in einer Erklärung der __main__ Modul. In diesem Text heißt es:

Dieses Modul stellt den (sonst anonymen) Bereich dar, in dem der   Das Hauptprogramm des Interpreters wird ausgeführt - Befehle lesen entweder von   Standardeingabe, von einer Skriptdatei oder von einer interaktiven Eingabeaufforderung. Es   ist diese Umgebung, in der die idiomatische "bedingte Skript" -Stanza steht   bewirkt, dass ein Skript ausgeführt wird:

if __name__ == '__main__':
    main()

412
2017-11-23 04:38



if __name__ == "__main__"ist der Teil, der ausgeführt wird, wenn das Skript von der Befehlszeile aus ausgeführt wird, beispielsweise mit einem Befehl python myscript.py.


92
2018-01-07 04:14



Was macht if __name__ == "__main__": machen?

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

Als einziger Spezialfall jedoch, in welchem ​​Python-Prozess Sie auch laufen, wie in mycode.py:

python mycode.py

Der ansonsten anonyme globale Namespace erhält den Wert von '__main__' zu seinem __name__.

Also einschließlich die letzten Zeilen

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

wird dazu führen, dass Ihr Skript eindeutig definiert ist main Funktion zum Ausfü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 und wenn Ihr Programm entscheidet:

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

57
2017-10-14 20:22



Es gibt viele verschiedene Einstellungen zur Funktionsweise des betreffenden Codes, das "How", aber für mich hat alles keinen Sinn ergeben, bis ich das "Warum" verstanden habe. Dies sollte besonders 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 __name__ == "__main__":
    main()

Was macht dieser Code eigentlich?

Wenn Sie ausführen xy.py, Sie import ab. Die import-Anweisung führt das Modul sofort beim Import aus, also abOperationen werden vor dem Rest von ausgeführt xyist es. Sobald fertig mit abgeht es weiter mit xy.

Der Interpreter verfolgt, mit welchen Skripten er läuft __name__. Wenn Sie ein Skript ausführen - egal, wie Sie es benannt haben - ruft der Interpreter es auf "__main__"Dies wird zum Master- oder Home-Skript, zu dem nach dem Ausführen eines externen Skripts zurückgekehrt wird.

Jedes andere Skript, das von diesem aufgerufen wird "__main__" Das Skript erhält seinen Dateinamen als sein __name__ (z.B., __name__ == "ab.py"). Daher die Linie if __name__ == "__main__": ist der Interpretertest, um festzustellen, ob das zu Beginn ausgeführte 'Home'-Skript interpretiert oder analysiert wird oder ob es vorübergehend in ein anderes (externes) Skript hineinspäht. Dies gibt dem Programmierer die Flexibilität, das Skript anders zu verhalten, wenn es direkt oder extern aufgerufen wird.

Lassen Sie uns den obigen Code durchgehen, um zu verstehen, was passiert, indem wir uns zunächst auf die nicht eingerückten Zeilen und deren Reihenfolge in den Skripten konzentrieren. Erinnere dich an diese Funktion - oder def - Blöcke machen nichts selbst, bis sie aufgerufen werden. Was der Dolmetscher sagen könnte, wenn er zu sich selbst murmelte:

  • Öffne xy.py als 'home' Datei; nennen "__main__" in dem __name__ Variable.
  • Importieren und öffnen Sie die Datei mit dem __name__ == "ab.py".
  • Oh, eine Funktion. Ich werde mich daran erinnern.
  • Ok, Funktion a(); Das habe ich gerade gelernt. Druck 'Eine Funktion in einer Datei".
  • Ende der Datei; zurück zu "__main__"!
  • Oh, eine Funktion. Ich werde mich daran erinnern.
  • Noch einer.
  • Funktion x(); ok, druck 'periphere Aufgabe: könnte in anderen Projekten nützlich sein".
  • Was ist das? Ein if Erklärung. Nun, die Bedingung wurde erfüllt (die Variable __name__wurde auf eingestellt "__main__"), also gehe ich in die main() Funktion und Druck 'Hauptfunktion: Hier ist die Aktion".

Die unteren zwei Zeilen bedeuten: "Wenn das der ist "__main__" oder 'home' Skript, führen Sie die aufgerufene Funktion aus main()". Deshalb wirst du eine sehen def main(): block up top, das den Hauptfluss der Script-Funktionalität enthält.

Warum das umsetzen?

Erinnern Sie sich an das, was ich zuvor über Importanweisungen gesagt habe? Wenn Sie ein Modul importieren, "erkennt" es es nicht nur und wartet auf weitere Anweisungen - es führt tatsächlich alle ausführbaren Operationen aus, die im Skript enthalten sind. Also, setze das Fleisch deines Drehbuchs in die main() Funktion isoliert es effektiv 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 das ist gängige Praxis main() wird normalerweise nicht extern aufgerufen. Sie fragen sich vielleicht noch etwas: wenn wir nicht anrufen main()Warum nennen wir das Skript überhaupt? Viele Leute strukturieren ihre Skripte mit eigenständigen Funktionen, die unabhängig vom Rest des Codes in der Datei ausgeführt werden. Sie werden dann später irgendwo anders im Skriptkörper aufgerufen. Was mich dazu bringt:

Aber der Code funktioniert ohne ihn

Ja, das ist richtig. Diese separaten Funktionen kann aus einem Inline-Skript aufgerufen werden, das nicht in einem enthalten ist main() Funktion. Wenn Sie (wie ich bin, in meinen frühen Lernphasen der Programmierung) daran gewöhnt sind, Inline-Skripte zu erstellen, die genau das tun, was Sie brauchen, und Sie werden versuchen, es wieder herauszufinden, wenn Sie diese Operation jemals wieder benötigen. Nun, Sie sind nicht an diese Art von interner Struktur zu Ihrem Code gewöhnt, weil es komplizierter zu bauen ist und nicht so intuitiv zu lesen ist.

Aber das ist ein Skript, das seine Funktionen wahrscheinlich nicht extern aufgerufen haben kann, denn wenn es so wäre, würde es sofort beginnen, Variablen zu berechnen und zuzuordnen. Und wenn Sie versuchen, eine Funktion wiederzuverwenden, ist das neue Skript wahrscheinlich eng genug mit dem alten verwandt, dass es widersprüchliche Variablen geben wird.

Durch das Aufteilen 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 aufrufen x()mit der Funktion 'x' aus "xy.py". (Vielleicht wird das dritte Wort einer gegebenen Textzeichenfolge groß geschrieben; ein NumPy-Array wird aus einer Liste von Zahlen erzeugt und quadriert; oder es wird eine 3D-Oberfläche vergrößert. Die Möglichkeiten sind grenzenlos.)

(Nebenbei, diese Frage enthält eine Antwort von @kindall, die mir endlich geholfen hat zu verstehen - das Warum, nicht das Wie. Leider wurde es als Duplikat markiert dieses, was ich denke, ist ein Fehler.)


47
2017-09-29 04:33



Wenn es bestimmte Aussagen in unserem Modul gibt (M.py) wir wollen ausgeführt werden, wenn es als main ausgeführt wird (nicht importiert), können wir diese Anweisungen (Testfälle, Druckanweisungen) unter diese setzen ifBlock.

Standardmäßig (wenn das Modul als Hauptprogramm ausgeführt wird, nicht importiert) __name__ Variable ist auf gesetzt "__main__"und wenn es importiert wird __name__ Variable erhält einen anderen Wert, höchstwahrscheinlich den Namen des Moduls ('M'). Dies ist hilfreich, wenn Sie verschiedene Varianten von Modulen zusammen ausführen und ihre spezifischen Eingabe- und Ausgabeanweisungen sowie Testfälle trennen.

Zusamenfassend, benutze das 'if __name__ == "main" 'Blockieren, um zu verhindern, dass (bestimmter) Code beim Import des Moduls ausgeführt wird.


39
2018-04-03 14:09



Schauen wir uns die Antwort abstrakter an:

Angenommen, wir haben diesen Code in x.py:

...
<Block A>
if __name__ == '__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, zum Beispiel "y.py", in dem xy importiert wird und der Code von dort ausgeführt wird (wie wenn eine Funktion in "x.py" ist) aufgerufen von y.py).


32
2018-01-20 17:48