Co to jest __main__.py?

326

Do czego służy __main__.pyplik, jaki kod powinienem w nim umieścić i kiedy powinienem go mieć?

Monika Sulik
źródło

Odpowiedzi:

320

Często program w języku Python jest uruchamiany przez nazwanie pliku .py w wierszu polecenia:

$ python my_program.py

Możesz także utworzyć katalog lub plik zip pełen kodu i dołączyć __main__.py. Następnie możesz po prostu nazwać katalog lub plik zip w wierszu poleceń, a program wykona __main__.pyautomatycznie:

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

Musisz sam zdecydować, czy Twoja aplikacja może skorzystać z takiego wykonania.


Zauważ, że __main__ moduł zwykle nie pochodzi z __main__.pypliku. Może, ale zwykle nie. Po uruchomieniu takiego skryptu python my_program.pyskrypt będzie działał jako __main__moduł zamiast my_programmodułu. Dzieje się tak również w przypadku modułów uruchamianych jako python -m my_modulelub na kilka innych sposobów.

Jeśli zobaczyłeś nazwę __main__w komunikacie o błędzie, nie musi to oznaczać, że powinieneś szukać __main__.pypliku.

Ned Batchelder
źródło
22
Znalazłem python -m program_diri python program_dirtrochę inaczej: ten ostatni nigdy nie działa __init__.pyw katalogu (jeśli taki istnieje).
brk
5
@brk: Teraz wydaje się, że tak nie jest. Właśnie próbowałem python3 program_diri zadziałało __init__.py.
mk12
@ mk12 Właśnie próbowałem, mogę potwierdzić ustalenia @ brk: python3 dirdziała, __main__.pyale nie __init__.py, podczas gdy python3 -m dirdziała oba.
Marcello Romani
1
@ mk12 Prawdopodobnie miałeś kod, w __main__.pyktórym uruchomiono import__init__.py
wim
100

Do czego służy __main__.pyplik?

Podczas tworzenia modułu w języku Python, moduł często wykonuje pewną funkcjonalność (zwykle zawartą w mainfunkcji), gdy jest uruchamiany jako punkt wejścia programu. Zwykle odbywa się to za pomocą następującego wspólnego idiomu umieszczonego na dole większości plików Pythona:

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

Możesz uzyskać tę samą semantykę dla pakietu Python z __main__.py. To jest monit powłoki Linuksa $, jeśli nie masz Bash (lub innej powłoki Posix) w systemie Windows, po prostu utwórz te pliki demo/__<init/main>__.pyz zawartością pomiędzy 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

(W powłoce Posix / Bash możesz zrobić powyższe bez << EOFs i kończąc na EOFs, wpisując Ctrl+ D, znak końca pliku na końcu każdej komendy cat)

I teraz:

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

Możesz to wywnioskować z dokumentacji. Dokumentacja mówi:

__main__ - Środowisko skryptowe najwyższego poziomu

'__main__'to nazwa zakresu, w którym wykonywany jest kod najwyższego poziomu. Moduł __name__jest ustawiony na równy, '__main__'gdy jest czytany ze standardowego wejścia, skryptu lub z interaktywnego monitu.

Moduł może odkryć, czy działa w głównym zakresie, sprawdzając jego własny __name__, co pozwala na wspólny idiom warunkowego wykonywania kodu w module, gdy jest on uruchamiany jako skrypt lub z, python -male nie, gdy jest importowany:

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

W przypadku pakietu ten sam efekt można osiągnąć, włączając __main__.pymoduł, którego zawartość zostanie wykonana po uruchomieniu modułu -m.

Zapinane na zamek

Możesz także spakować to do jednego pliku i uruchomić z wiersza poleceń w ten sposób - ale pamiętaj, że spakowane pakiety nie mogą wykonywać podpakietów lub podmodułów jako punktu wejścia:

$ python -m zipfile -c demo.zip demo/*
$ python demo.zip
demo/__main__.py executed
demo/__init__.py executed
main() executed
Aaron Hall
źródło
31

__main__.pyjest używany w programach Python w plikach zip. __main__.pyPlik zostanie wykonany, gdy plik zip w uruchomieniu. Na przykład, jeśli plik zip był taki:

test.zip
     __main__.py

i treść __main__.pybyła

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

Gdybyśmy mieli biec python test.zip world, ucieklibyśmy hello world.

Tak więc __main__.pyplik jest uruchamiany, gdy python jest wywoływany w pliku zip.

Niebieska Papryka
źródło
23

Tworzysz __main__.pyw, yourpackageaby był wykonywalny jako:

$ python -m yourpackage
anatoly techtonik
źródło
1
-mdziała, jeśli tylko program jest dostępny jako moduł, w przeciwnym razie możesz użyć python <yourpackage>UWAGA: bez -mopcji
Benyamin Jafari
1
@BenyaminJafari nie jest możliwe napisanie programu Python z linii poleceń, który nie jest dostępny jako moduł . Może miałeś na myśli package?
anatoly techtonik,
1
kiedy tworzymy pakiet Pythona, który zawiera główny plik .py, uruchomienie go python -m <yourproject>nie działa, -mjest opcją redundantną, ale python <yourpackage>działa dobrze.
Benyamin Jafari,
@BenyaminJafari Flaga -m robi różnicę w niektórych przypadkach. Wykonywanie z katalogu ai zakładanie skryptu a/b/c/__main__.py... python -m b.czostanie wykonane z katalogu, aa import skryptu głównego będzie względny a. Ale python b/cwykona się z zakresu importu katalogu, cwięc jakikolwiek import jak w skrypcie głównym jak import b.dnie powiedzie się.
MikeCPT
14

Jeśli skrypt jest katalogiem lub plikiem ZIP, a nie pojedynczym plikiem Pythona, __main__.pyzostanie wykonany, gdy „skrypt” zostanie przekazany jako argument do interpretera Pythona.

Wooble
źródło