¿Qué es __main__.py?

326

¿Para qué es el __main__.pyarchivo, qué tipo de código debo poner en él y cuándo debo tener uno?

Monika Sulik
fuente

Respuestas:

320

A menudo, un programa Python se ejecuta nombrando un archivo .py en la línea de comando:

$ python my_program.py

También puede crear un directorio o archivo zip lleno de código e incluir a __main__.py. Luego puede simplemente nombrar el directorio o el archivo zip en la línea de comando, y se ejecuta __main__.pyautomáticamente:

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

Tendrá que decidir por sí mismo si su aplicación podría beneficiarse de una ejecución como esta.


Tenga en cuenta que un __main__ módulo generalmente no proviene de un __main__.pyarchivo. Puede, pero generalmente no lo hace. Cuando ejecuta un script como python my_program.py, el script se ejecutará como el __main__módulo en lugar del my_programmódulo. Esto también sucede para los módulos que se ejecutan como python -m my_module, o de varias otras maneras.

Si vio el nombre __main__en un mensaje de error, eso no significa necesariamente que deba buscar un __main__.pyarchivo.

Ned Batchelder
fuente
22
Encontré python -m program_diry python program_dirun poco diferente: este último nunca se ejecuta __init__.pyen el directorio (si hay uno).
brk
55
@brk: Ese no parece ser el caso ahora. Solo lo intenté python3 program_diry funcionó __init__.py.
mk12
@ mk12 Lo acabo de probar. Puedo confirmar los hallazgos de @ brk: python3 dirfunciona __main__.pypero no __init__.py, mientras que python3 -m direjecuta ambos.
Marcello Romani
1
@ mk12 Probablemente tenía algún código dentro del __main__.pycual se activó la importación de__init__.py
wim
100

¿Para qué es el __main__.pyarchivo?

Al crear un módulo Python, es común hacer que el módulo ejecute alguna funcionalidad (generalmente contenida en una mainfunción) cuando se ejecuta como el punto de entrada del programa. Esto normalmente se hace con el siguiente idioma común colocado en la parte inferior de la mayoría de los archivos de Python:

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

Puede obtener la misma semántica para un paquete Python con __main__.py. Este es un indicador de shell de Linux $, si no tiene Bash (u otro shell de Posix) en Windows, simplemente cree estos archivos demo/__<init/main>__.pycon contenido entre 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

(En un shell Posix / Bash, puede hacer lo anterior sin la << EOFsy terminando EOFs ingresando Ctrl+ D, el carácter de fin de archivo, al final de cada comando cat)

Y ahora:

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

Puede derivar esto de la documentación. La documentación dice:

__main__ - Entorno de script de nivel superior

'__main__'es el nombre del ámbito en el que se ejecuta el código de nivel superior. Un módulo __name__se establece igual que '__main__'cuando se lee desde una entrada estándar, un script o desde una solicitud interactiva.

Un módulo puede descubrir si se está ejecutando o no en el ámbito principal comprobando el suyo propio __name__, lo que permite un modismo común para ejecutar código condicionalmente en un módulo cuando se ejecuta como un script o con, python -mpero no cuando se importa:

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

Para un paquete, se puede lograr el mismo efecto al incluir un __main__.pymódulo, cuyo contenido se ejecutará cuando se ejecute el módulo -m.

Cremallera

También puede empaquetar esto en un solo archivo y ejecutarlo desde la línea de comando de esta manera, pero tenga en cuenta que los paquetes comprimidos no pueden ejecutar subpaquetes o submódulos como punto de entrada:

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

__main__.pyse usa para programas de python en archivos zip. El __main__.pyarchivo se ejecutará cuando se ejecute el archivo zip. Por ejemplo, si el archivo zip era así:

test.zip
     __main__.py

y el contenido de __main__.pywas

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

Entonces, si fuéramos a correr python test.zip world, saldríamos hello world.

Entonces, el __main__.pyarchivo se ejecuta cuando se llama a python en un archivo zip.

Pimientos azules
fuente
23

Se crea __main__.pyen yourpackagepara que sea ejecutable como:

$ python -m yourpackage
anatoly techtonik
fuente
1
-mfunciona si solo se puede acceder al programa como un módulo, de lo contrario podría usar python <yourpackage>NOTA: sin -mopción
Benyamin Jafari
1
@BenyaminJafari no es posible escribir un programa Python de línea de comandos que no sea accesible como módulo . Tal vez lo has querido decir package?
anatoly techtonik
1
cuando creamos un paquete de Python que contiene el .py principal , ejecutarlo python -m <yourproject>no funciona, -mes una opción redundante, pero python <yourpackage>funciona bien.
Benyamin Jafari
@BenyaminJafari La bandera -m hace la diferencia en algunos casos. Ejecutar desde el directorio ay asumir el script a/b/c/__main__.py... python -m b.cse ejecutará desde el directorio ay las importaciones del script principal serán relativas a a. Pero python b/cse ejecutará desde el alcance de importación de dir cy, por lo tanto, cualquier importación como en el script principal import b.dfallará.
MikeCPT
14

Si su secuencia de comandos es un directorio o un archivo ZIP en lugar de un solo archivo de Python, __main__.pyse ejecutará cuando la "secuencia de comandos" se pase como argumento al intérprete de Python.

Wooble
fuente