Was bewirkt dies?
if __name__ == "__main__":
print("Hello world!")
Was bewirkt dies?
if __name__ == "__main__":
print("Hello world!")
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.
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]))
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).
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).
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.
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.
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.
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:
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 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.
34 Stimmen
Nur fürs Protokoll - was ist " Haupt ": docs.python.org/3/reference/ und was ist " Name ": docs.python.org/3/reference/