Was ist __main__.py?

325

Wofür ist die __main__.pyDatei, welche Art von Code sollte ich einfügen und wann sollte ich einen haben?

Monika Sulik
quelle

Antworten:

318

Oft wird ein Python-Programm ausgeführt, indem eine .py-Datei in der Befehlszeile benannt wird:

$ python my_program.py

Sie können auch ein Verzeichnis oder eine Zip-Datei mit Code erstellen und a einschließen __main__.py. Dann können Sie einfach das Verzeichnis oder die Zip-Datei in der Befehlszeile benennen und es führt __main__.pyautomatisch Folgendes aus :

$ python my_program_dir
$ python my_program.zip
# Or, if the program is accessible as a module
$ python -m my_program

Sie müssen selbst entscheiden, ob Ihre Anwendung von einer solchen Ausführung profitieren könnte.


Beachten Sie, dass ein __main__ Modul normalerweise nicht aus einer __main__.pyDatei stammt. Es kann, aber normalerweise nicht. Wenn Sie ein Skript wie ausführen python my_program.py, wird das Skript als __main__Modul anstelle des my_programModuls ausgeführt. Dies geschieht auch für Module, die als python -m my_moduleoder auf verschiedene andere Arten ausgeführt werden.

Wenn Sie den Namen __main__in einer Fehlermeldung gesehen haben, bedeutet dies nicht unbedingt, dass Sie nach einer __main__.pyDatei suchen sollten .

Ned Batchelder
quelle
22
Ich fand python -m program_dirund python program_direin bisschen anders: Letzteres läuft nie __init__.pyim Verzeichnis (falls es eines gibt).
Brk
5
@brk: Das scheint jetzt nicht der Fall zu sein. Ich habe es gerade versucht python3 program_dirund es lief __init__.py.
mk12
@ MK12 Ich habe gerade versucht I @ brk Feststellungen bestätigen kann: python3 dirLäufe __main__.pyaber nicht __init__.py, während python3 -m dirläuft beides.
Marcello Romani
1
@ mk12 Wahrscheinlich hatten Sie einen Code, __main__.pyder den Import von__init__.py
wim
100

Wofür ist die __main__.pyDatei?

Beim Erstellen eines Python-Moduls ist es üblich, dass das Modul einige Funktionen (normalerweise in einer mainFunktion enthalten) ausführt, wenn es als Einstiegspunkt des Programms ausgeführt wird. Dies geschieht normalerweise mit der folgenden allgemeinen Redewendung, die am Ende der meisten Python-Dateien steht:

if __name__ == '__main__':
    # execute only if run as the entry point into the program
    main()

Sie können dieselbe Semantik für ein Python-Paket mit erhalten __main__.py. Dies ist eine Eingabeaufforderung für die Linux-Shell $. Wenn Sie unter Windows keine Bash (oder eine andere Posix-Shell) haben, erstellen Sie diese Dateien einfach demo/__<init/main>__.pymit Inhalten zwischen den EOFs:

$ mkdir demo
$ cat > demo/__init__.py << EOF
print('demo/__init__.py executed')
def main():
    print('main executed')
EOF
$ cat > demo/__main__.py << EOF
print('demo/__main__.py executed')
from __init__ import main
main()
EOF

(In einer Posix / Bash-Shell können Sie die obigen Schritte ohne << EOFs und end EOFs ausführen , indem Sie am Ende jedes cat-Befehls Ctrl+ D, das Zeichen für das Dateiende, eingeben.)

Und nun:

$ python demo
demo/__main__.py executed
demo/__init__.py executed
main executed

Sie können dies aus der Dokumentation ableiten. Das Dokumentation sagt:

__main__ - Skriptumgebung der obersten Ebene

'__main__'ist der Name des Bereichs, in dem Code der obersten Ebene ausgeführt wird. Ein Modul __name__wird gleich gesetzt'__main__' wenn es von einer Standardeingabe, einem Skript oder einer interaktiven Eingabeaufforderung gelesen wird.

Ein Modul kann feststellen, ob es im Hauptbereich ausgeführt wird oder nicht, indem es seine eigene überprüft. Dies __name__ermöglicht eine allgemeine Redewendung für die bedingte Ausführung von Code in einem Modul, wenn es als Skript ausgeführt wird oder mit, python -maber nicht, wenn es importiert wird:

if __name__ == '__main__':
      # execute only if run as a script
      main()

Für ein Paket kann der gleiche Effekt erzielt werden, indem ein __main__.pyModul eingeschlossen wird, dessen Inhalt ausgeführt wird, wenn das Modul mit ausgeführt wird -m.

Reißverschluss

Sie können dies auch in eine einzelne Datei packen und wie folgt über die Befehlszeile ausführen. Beachten Sie jedoch, dass komprimierte Pakete keine Unterpakete oder Submodule als Einstiegspunkt ausführen können:

$ python -m zipfile -c demo.zip demo/*
$ python demo.zip
demo/__main__.py executed
demo/__init__.py executed
main() executed
Aaron Hall
quelle
31

__main__.pywird für Python-Programme in Zip-Dateien verwendet. Die __main__.pyDatei wird ausgeführt, wenn die Zip-Datei ausgeführt wird. Wenn die Zip-Datei beispielsweise so war:

test.zip
     __main__.py

und der Inhalt von __main__.pywar

import sys
print "hello %s" % sys.argv[1]

Wenn wir dann rennen python test.zip worldwürden, würden wir hello worldraus.

Die __main__.pyDatei wird also ausgeführt, wenn Python in einer Zip-Datei aufgerufen wird.

Blue Peppers
quelle
23

Sie erstellen __main__.pyin yourpackage, um es ausführbar zu machen als:

$ python -m yourpackage
anatoly techtonik
quelle
1
-mfunktioniert, wenn nur das Programm als Modul zugänglich ist, sonst können Sie verwenden python <yourpackage>HINWEIS: ohne -mOption
Benyamin Jafari
1
@BenyaminJafari Es ist nicht möglich, ein Befehlszeilen-Python-Programm zu schreiben, auf das als Modul nicht zugegriffen werden kann . Vielleicht hast du gemeint package?
Anatoly Techtonik
1
wenn wir ein Python - Paket erstellen, das die enthält Haupt- Py, laufen sie python -m <yourproject>nicht funktioniert, -mist eine redundante Option, aber python <yourpackage>gut funktioniert.
Benyamin Jafari
@BenyaminJafari Das Flag -m macht in einigen Fällen einen Unterschied. Die Ausführung aus dem Verzeichnis und die aAnnahme, dass das Skript a/b/c/__main__.py... python -m b.caus dem Verzeichnis ausgeführt wird aund die Importe des Hauptskripts relativ zu sind a. Aber python b/cwird aus dem Importumfang dir ausführen cund so alle Importe wie im Haupt Skript wie import b.dfehl.
MikeCPT
14

Wenn Ihr Skript ein Verzeichnis oder eine ZIP-Datei anstelle einer einzelnen Python-Datei ist, __main__.pywird es ausgeführt, wenn das "Skript" als Argument an den Python-Interpreter übergeben wird.

Wooble
quelle