Che cos'è __main__.py?


326

A cosa serve il __main__.pyfile, che tipo di codice dovrei inserire e quando dovrei averne uno?

Risposte:


320

Spesso, un programma Python viene eseguito nominando un file .py sulla riga di comando:

$ python my_program.py

Puoi anche creare una directory o un file zip pieno di codice e includere a __main__.py. Quindi puoi semplicemente nominare la directory o il file zip sulla riga di comando ed eseguirà __main__.pyautomaticamente:

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

Dovrai decidere tu stesso se l'applicazione potrebbe trarre vantaggio dall'esecuzione in questo modo.


Si noti che un __main__ modulo di solito non proviene da un __main__.pyfile. Può, ma di solito no. Quando si esegue uno script simile python my_program.py, lo script verrà eseguito come __main__modulo anziché come my_programmodulo. Ciò accade anche per i moduli eseguiti come python -m my_moduleo in molti altri modi.

Se hai visto il nome __main__in un messaggio di errore, ciò non significa necessariamente che dovresti cercare un __main__.pyfile.


22
Ho trovato python -m program_dire python program_dirun po 'diverso: quest'ultimo non funziona mai __init__.pynella directory (se ce n'è uno).
vantarsi

5
@brk: non sembra essere il caso adesso. Ho appena provato python3 program_dire ha funzionato __init__.py.
MK12,

@ mk12 L'ho appena provato Posso confermare i risultati di @ brk: python3 dircorre __main__.pyma non __init__.py, mentre python3 -m dircorre entrambi.
Marcello Romani,

1
@ mk12 Probabilmente avevi del codice all'interno del __main__.pyquale è stata avviata l'importazione di__init__.py
wim il

100

A cosa serve il __main__.pyfile?

Quando si crea un modulo Python, è comune fare in modo che il modulo esegua alcune funzionalità (di solito contenute in una mainfunzione) quando eseguito come punto di ingresso del programma. Questo in genere viene fatto con il seguente linguaggio comune posizionato nella parte inferiore della maggior parte dei file Python:

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

Puoi ottenere la stessa semantica per un pacchetto Python con __main__.py. Questo è un prompt della shell linux $, se non hai Bash (o un'altra shell Posix) su Windows, devi semplicemente creare questi file demo/__<init/main>__.pycon i contenuti tra le 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 una shell Posix / Bash, puoi fare quanto sopra senza la << EOFs e terminare la EOFs inserendo Ctrl+ D, il carattere di fine del file, alla fine di ogni comando cat)

E adesso:

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

Puoi ricavarlo dalla documentazione. La documentazione dice:

__main__ - Ambiente di script di livello superiore

'__main__'è il nome dell'ambito in cui viene eseguito il codice di livello superiore. Un modulo __name__è impostato uguale a '__main__'quando viene letto dall'input standard, da uno script o da un prompt interattivo.

Un modulo può scoprire se è in esecuzione nell'ambito principale controllando il proprio __name__, il che consente un linguaggio comune per l'esecuzione condizionale del codice in un modulo quando viene eseguito come script o con python -mma non quando viene importato:

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

Per un pacchetto, lo stesso effetto può essere ottenuto includendo un __main__.pymodulo, il cui contenuto verrà eseguito quando il modulo viene eseguito -m.

zip

Puoi anche comprimerlo in un singolo file ed eseguirlo dalla riga di comando in questo modo - ma nota che i pacchetti compressi non possono eseguire sotto-pacchetti o sottomoduli come punto di ingresso:

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

31

__main__.pyè usato per i programmi Python nei file zip. Il __main__.pyfile verrà eseguito quando il file zip è in esecuzione. Ad esempio, se il file zip era come tale:

test.zip
     __main__.py

e il contenuto di __main__.pyera

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

Quindi se dovessimo correre python test.zip worldscapperemmo hello world.

Quindi il __main__.pyfile viene eseguito quando python viene chiamato su un file zip.


23

Si crea __main__.pyin yourpackageper renderlo eseguibile come:

$ python -m yourpackage

1
-mfunziona se solo il programma è accessibile come modulo, altrimenti è possibile utilizzare python <yourpackage>NOTA: senza -mopzione
Benyamin Jafari

1
@BenyaminJafari non è possibile scrivere sulla riga di comando un programma Python non accessibile come modulo . Forse intendevi package?
Anatoly Techtonik,

1
quando creiamo un pacchetto Python che contiene il .py principale , per eseguirlo python -m <yourproject>non funziona, -mè un'opzione ridondante, ma python <yourpackage>funziona bene.
Benyamin Jafari,

@BenyaminJafari Il flag -m fa la differenza in alcuni casi. L'esecuzione dalla directory ae l'assunzione dello script a/b/c/__main__.py... python -m b.cverranno eseguiti dalla directory ae le importazioni dello script principale saranno relative a. Ma python b/cverrà eseguito dall'ambito di importazione di dir ce quindi eventuali importazioni come nello script principale come import b.dfalliranno.
MikeCPT,

14

Se lo script è una directory o un file ZIP anziché un singolo file Python, __main__.pyverrà eseguito quando lo "script" viene passato come argomento all'interprete Python.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.