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/

27voto

Mit einfachen Worten:

Der Code, den Sie unter if __name__ == "__main__": wird nur aufgerufen, wenn Ihre Python-Datei als "python example1.py" ausgeführt wird.

Wenn Sie jedoch Ihre Python-Datei "example1.py" als Modul importieren möchten, um mit einer anderen Python-Datei, beispielsweise "example2.py", zu arbeiten, muss der Code unter if __name__ == "__main__": wird nicht ausgeführt und entfaltet keine Wirkung.

22voto

kgf3JfUtW Punkte 11416

Sie können die Datei als Skript sowie eine importierbares Modul .

fibo.py (ein Modul namens 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 __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

Referenz: https://docs.python.org/3.5/tutorial/modules.html

22voto

personal_cloud Punkte 3453

Der Grund für

if __name__ == "__main__":
    main()

ist in erster Linie zur Vermeidung der Einfuhrsperre Probleme, die sich ergeben würden aus mit direkt importiertem Code . Sie wollen main() auszuführen, wenn Ihre Datei direkt aufgerufen wurde (das ist die __name__ == "__main__" Fall), aber wenn Ihr Code importiert wurde, muss der Importeur Ihren Code aus dem echten Hauptmodul eingeben, um Probleme mit der Importsperre zu vermeiden.

Ein Nebeneffekt ist, dass Sie sich automatisch bei einer Methodik anmelden, die mehrere Einstiegspunkte unterstützt. Sie können Ihr Programm ausführen mit main() als Einstiegspunkt, aber das müssen Sie nicht . Während setup.py erwartet main() Andere Tools verwenden alternative Einstiegspunkte. Um Ihre Datei zum Beispiel als gunicorn Prozess, definieren Sie eine app() Funktion anstelle einer main() . Genau wie bei setup.py , gunicorn importiert Ihren Code, so dass Sie nicht wollen, dass er etwas tut, während er importiert wird (wegen des Problems der Importsperre).

21voto

tripleee Punkte 155951

Wenn Sie ein Anfänger sind, ist die einzige Antwort, die Sie im Moment brauchen, wahrscheinlich, dass dieser Code ist unnötig für ein einfaches Skript. Es ist nur nützlich, wenn Sie in der Lage sein wollen import Ihr Skript (oder unpickle usw.; siehe die anderen Antworten hier für einige andere Szenarien, die nicht für Anfänger geeignet sind).

Etwas ausführlicher: Nehmen wir an, Sie haben ein einfaches Skript fib.py (angepasst von diese Antwort ):

# XXX FIXME: useless (see below)
if __name__ == "__main__":
    n = int(input('Write a number: '))
    a, b = 0, 1
    while b < n:
        a, b = b, a+b
    print('Fibonacci number %i: %i' % (n, b))

Wenn Sie nun einfach Folgendes ausführen python fib.py funktioniert es gut. Aber __name__ wird immer "__main__" in diesem Szenario, so dass die Bedingung eigentlich unnötig ist. Das Skript könnte vereinfacht werden, indem man einfach

n = int(input('Write a number: '))
a, b = 0, 1
while b < n:
    a, b = b, a+b
print('Fibonacci number %i: %i' % (n, b))

Nun, Sie können nicht import fib mit der neuen Version, aber wenn Sie das nicht von vornherein vorhatten, ist diese Version sogar besser, weil sie einfacher und klarer ist.

Wenn Sie tun in der Lage sein wollen import fib ist die erste Version ebenfalls nutzlos, da der nützliche Code in einem Abschnitt steht, der nicht ausgeführt wird, wenn Sie import diese Datei (in diesem Fall __name__ wird nicht "__main__" ). In diesem Fall sollte der Code so umstrukturiert werden, dass die nützlichen Teile in einer Funktion enthalten sind, die Sie bei Bedarf ausführen können, nachdem Sie import es.

def main():
    n = int(input('Write a number: '))
    a, b = 0, 1
    while b < n:
        a, b = b, a+b
    print('Fibonacci number %i: %i' % (n, b))

if __name__ == "__main__":
    main()

Nun, wenn Sie import fib der Aufruf an main() wird nicht ausgeführt; aber wenn Sie python fib.py wird es.

Noch besser wäre es, den wiederverwendbaren Teil (die eigentliche Berechnung) von der für den Benutzer sichtbaren Eingabe/Ausgabe zu trennen:

def fibn(n: int) -> int:
    a, b = 0, 1
    while b < n:
        a, b = b, a+b
    return b

def main() -> None:
    n = int(input('Write a number: '))
    print('Fibonacci number %i: %i' % (n, fibn(n)))

if __name__ == "__main__":
    main()

Jetzt können Sie from fib import fibn und rufen Sie die fibn() Funktion aus dem Code, die diese Aufgabe erfüllt import .

(Ich habe die Funktion fibn() nur um zu verdeutlichen, was in diesem Beispiel was ist. Im wirklichen Leben könnte man es so nennen fib() und tun from fib import fib .)

In ähnlicher Weise könnten Sie import und rufen Sie die main Funktion, wenn Sie sie wiederverwenden möchten.

Um auf den Code in der Frage zurückzukommen, würde ich den Code ebenfalls aus der if in eine Funktion umwandeln, so dass der Aufrufer diese Funktion bei Bedarf aufrufen kann.

def main():
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

if __name__ == "__main__":
    main()

Dadurch ändert sich der Anwendungsbereich der lock Variable; wenn der umgebende Code Zugriff auf sie benötigt, müssen Sie sie zu global (oder, vielleicht besser, refactor main à return lock und lassen Sie den Aufrufer den Wert in einer eigenen lokalen Variablen erfassen).

0 Stimmen

Ich habe den Beispielcode einfach gehalten, um Ablenkungen zu vermeiden; im wirklichen Leben müssen Sie sich mit input etwas zurückgibt, das keine Zahl ist, und natürlich sollte eine echte Fibonacci-Funktion vielleicht optimiert werden, um zu vermeiden, dass bei jedem Aufruf der Anfang der Folge neu berechnet wird.

0 Stimmen

El n: int y -> int Typ-Anmerkungen erfordern Python >= 3.6

0 Stimmen

Die Konvention für die Reihenfolge der Fibonacci-Zahlen ist nicht ganz in Stein gemeißelt. Die übliche Konvention ist, dass die erste Zahl 0 ist, aber mathematisch gesehen ist dies konventionell F(0) . Sie könnten das Ergebnis des einfachen Skripts als einen Fehler betrachten und es entsprechend korrigieren.

20voto

Rishi Bansal Punkte 3151

Jedes Modul in Python hat ein Attribut namens __name__ . Der Wert von __name__ Attribut ist __main__ wenn das Modul direkt ausgeführt wird, wie python my_module.py . Andernfalls (wie wenn Sie sagen import my_module ) den Wert von __name__ ist der Name des Moduls.

Ein kleines Beispiel, um es kurz zu erklären.

Drehbuch test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

Wir können dies direkt ausführen als

python test.py

Ausgabe

Value of __name__ 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 aus auf:

Drehbuch 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

Es ist also selbsterklärend, dass Sie beim Aufruf von Test aus einem anderen Skript, wenn Schleife __name__ sur test.py wird nicht ausgeführt.

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