¿Qué hace si __name__ == "__main__": hacer?

6067

Dado el siguiente código, ¿qué hace if __name__ == "__main__":?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while True:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)

if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
Devoto
fuente
¿La if __name__ == "__main__":condición de bloque ha quedado obsoleta / obsoleta hasta Python 3? He encontrado información que lo indica.
carloswm85
2
@ carloswm85 Eso no es cierto.
Giorgos Myrianthous

Respuestas:

6649

Cada vez que el intérprete de Python lee un archivo fuente, hace dos cosas:

  • establece algunas variables especiales como __name__, y luego

  • ejecuta todo el código encontrado en el archivo.

Veamos cómo funciona esto y cómo se relaciona con su pregunta sobre las __name__comprobaciones que siempre vemos en los scripts de Python.

Muestra de código

Usemos una muestra de código ligeramente diferente para explorar cómo funcionan las importaciones y los scripts. Supongamos que lo siguiente está en un archivo llamado foo.py.

# Suppose this is foo.py.

print("before import")
import math

print("before functionA")
def functionA():
    print("Function A")

print("before functionB")
def functionB():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

Variables especiales

Cuando el intérprete de Python lee un archivo fuente, primero define algunas variables especiales. En este caso, nos importa la __name__variable.

Cuando su módulo es el programa principal

Si está ejecutando su módulo (el archivo fuente) como el programa principal, p. Ej.

python foo.py

el intérprete asignará la cadena codificada "__main__"a la __name__variable, es decir

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

Cuando su módulo es importado por otro

Por otro lado, suponga que otro módulo es el programa principal e importa su módulo. Esto significa que hay una declaración como esta en el programa principal, o en algún otro módulo que importa el programa principal:

# Suppose this is in some other main program.
import foo

El intérprete buscará su foo.pyarchivo (junto con la búsqueda de algunas otras variantes), y antes de ejecutar ese módulo, asignará el nombre "foo"de la declaración de importación a la __name__variable, es decir

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

Ejecutando el Código del Módulo

Después de configurar las variables especiales, el intérprete ejecuta todo el código del módulo, una declaración a la vez. Es posible que desee abrir otra ventana al lado con el ejemplo de código para que pueda seguir esta explicación.

Siempre

  1. Imprime la cadena "before import"(sin comillas).

  2. Carga el mathmódulo y lo asigna a una variable llamada math. Esto es equivalente a reemplazar import mathcon lo siguiente (tenga en cuenta que __import__es una función de bajo nivel en Python que toma una cadena y desencadena la importación real):

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. Imprime la cuerda "before functionA".

  2. Ejecuta el defbloque, crea un objeto de función y luego asigna ese objeto de función a una variable llamada functionA.

  3. Imprime la cuerda "before functionB".

  4. Ejecuta el segundo defbloque, crea otro objeto de función y luego lo asigna a una variable llamada functionB.

  5. Imprime la cuerda "before __name__ guard".

Solo cuando su módulo es el programa principal

  1. Si su módulo es el programa principal, verá que __name__efectivamente se configuró en "__main__"y llama a las dos funciones, imprime las cadenas "Function A"y "Function B 10.0".

Solo cuando su módulo es importado por otro

  1. (en cambio ) Si su módulo no es el programa principal pero fue importado por otro, entonces __name__lo será "foo", no "__main__", y omitirá el cuerpo de la ifdeclaración.

Siempre

  1. Imprimirá la cadena "after __name__ guard"en ambas situaciones.

Resumen

En resumen, esto es lo que se imprimiría en los dos casos:

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

¿Por qué funciona de esta manera?

Naturalmente, podría preguntarse por qué alguien querría esto. Bueno, a veces desea escribir un .pyarchivo que pueda ser utilizado por otros programas y / o módulos como un módulo, y también puede ejecutarse como el programa principal en sí. Ejemplos:

  • Su módulo es una biblioteca, pero desea tener un modo de script donde ejecute algunas pruebas unitarias o una demostración.

  • Su módulo solo se usa como programa principal, pero tiene algunas pruebas unitarias, y el marco de prueba funciona importando .pyarchivos como su script y ejecutando funciones de prueba especiales. No desea que intente ejecutar el script solo porque está importando el módulo.

  • Su módulo se utiliza principalmente como programa principal, pero también proporciona una API fácil de usar para programadores para usuarios avanzados.

Más allá de esos ejemplos, es elegante que ejecutar un script en Python solo esté configurando algunas variables mágicas e importando el script. "Ejecutar" el script es un efecto secundario de importar el módulo del script.

Comida para el pensamiento

  • Pregunta: ¿Puedo tener múltiples __name__bloques de verificación? Respuesta: es extraño hacerlo, pero el lenguaje no te detendrá.

  • Supongamos que lo siguiente está adentro foo2.py. ¿Qué pasa si dices python foo2.pyen la línea de comandos? ¿Por qué?

# Suppose this is foo2.py.

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
  • Ahora, descubra qué sucederá si elimina el __name__check in foo3.py:
# Suppose this is foo3.py.

def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
print("m1")
functionA()
print("m2")
print("t2")
  • ¿Qué hará esto cuando se use como script? Cuando se importa como un módulo?
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")

print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")
Señor fooz
fuente
14
Por curiosidad: ¿qué sucede si ejecuto subprocess.run('foo_bar.py')un script de Python? Supongo que foo_bareso se iniciará __name__ = '__main__'al igual que cuando escribo foo_bar.pycmd manualmente. ¿Es ese el caso? Teniendo en cuenta la respuesta de @MrFooz, no debería haber ningún problema para hacer esto y tener tantos módulos "principales" a la vez como quiera. Incluso cambiar el __name__valor o tener varias instancias creadas de forma independiente (o instancias que se crearon entre sí subprocess) interactúan entre sí, debería ser lo habitual para Python. ¿Echo de menos algo?
hajef
12
@hajef Tienes razón sobre cómo funcionarían las cosas subprocess.run. Dicho esto, una forma generalmente mejor de compartir código entre scripts es crear módulos y hacer que los scripts llamen a los módulos compartidos en lugar de invocarse entre ellos como scripts. Es difícil depurar subprocess.runllamadas ya que la mayoría de los depuradores no saltan los límites del proceso, puede agregar una sobrecarga del sistema no trivial para crear y destruir los procesos adicionales, etc.
Sr. Fooz
44
Tengo una duda en el ejemplo de foo2.py en la sección de alimentos para el pensamiento. ¿Qué hace la función de importación de foo2.py B? En mi opinión, solo importa foo2.py desde la función
B
1
@MrFooz Nunca tuve la intención de hacer algo como esto xD Simplemente se me ocurrió y me di cuenta de que era lo suficientemente extraño como para ayudar a la gente. envolviendo sus mentes alrededor de este tipo de cosas. @ user471651 ¿Por qué debería from foo2 import functionBimportar foo2 desde la función B ? Esa es una contorsión semántica. from module import methodimporta el método desde el módulo.
hajef
2
Uno de los módulos que pueden importar su código es multiprocessing, en particular, hacer que esta prueba sea necesaria en Windows.
Yann Vernier
1801

Cuando su script se ejecuta pasándolo como un comando al intérprete de Python,

python myscript.py

todo el código que está en el nivel de sangría 0 se ejecuta. Las funciones y clases que están definidas están, bien, definidas, pero ninguno de sus códigos se ejecuta. A diferencia de otros lenguajes, no hay una main()función que se ejecute automáticamente: la main()función es implícitamente todo el código en el nivel superior.

En este caso, el código de nivel superior es un ifbloque. __name__es una variable incorporada que evalúa el nombre del módulo actual. Sin embargo, si un módulo se está ejecutando directamente (como en el caso myscript.pyanterior), en su __name__lugar, se establece en la cadena "__main__". Por lo tanto, puede probar si su script se está ejecutando directamente o si otra cosa lo está importando al probar

if __name__ == "__main__":
    ...

Si su secuencia de comandos se está importando a otro módulo, se importarán sus diversas funciones y definiciones de clase y se ejecutará su código de nivel superior, pero el código en el cuerpo de la ifcláusula anterior no se ejecutará ya que la condición es no se cumplen. Como ejemplo básico, considere los siguientes dos scripts:

# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

Ahora, si invoca al intérprete como

python one.py

La salida será

top-level in one.py
one.py is being run directly

Si corres en su two.pylugar:

python two.py

Usted obtiene

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

Por lo tanto, cuando el módulo onese carga, es __name__igual en "one"lugar de "__main__".

Adam Rosenfield
fuente
Impresionante respuesta, esta fue la respuesta más clara en mi opinión. +1!
TheTechRobo36414519
+1 para esa forma de pensarlo: la primera línea con sangría se ejecuta solo al principio, hasta que ejecute funciones en esa primera línea
Elijah Mock
719

La explicación más simple para la __name__variable (imho) es la siguiente:

Crea los siguientes archivos.

# a.py
import b

y

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

Ejecutarlos te dará esta salida:

$ python a.py
Hello World from b!

Como puede ver, cuando se importa un módulo, Python establece globals()['__name__']en este módulo el nombre del módulo. Además, al importar todo el código del módulo se está ejecutando. Como la ifdeclaración se evalúa a Falseesta parte no se ejecuta.

$ python b.py
Hello World from __main__!
Hello World again from __main__!

Como puede ver, cuando se ejecuta un archivo, Python se establece globals()['__name__']en este archivo en "__main__". Esta vez, la ifdeclaración se evalúa Truey se está ejecutando.

Pi.
fuente
513

¿Qué hace el if __name__ == "__main__":?

Para resumir los conceptos básicos:

  • La variable global __name__, en el módulo que es el punto de entrada a su programa, es '__main__'. De lo contrario, es el nombre por el que importa el módulo.

  • Entonces, el código debajo del ifbloque solo se ejecutará si el módulo es el punto de entrada a su programa.

  • Permite que el código en el módulo pueda ser importado por otros módulos, sin ejecutar el siguiente bloque de código en la importación.


¿Porqué necesitamos esto?

Desarrollando y probando su código

Digamos que está escribiendo un script Python diseñado para ser utilizado como un módulo:

def do_important():
    """This function does something very important"""

Usted podría probar el módulo mediante la adición de esta llamada de la función a la parte inferior:

do_important()

y ejecutarlo (en un símbolo del sistema) con algo como:

~$ python important.py

El problema

Sin embargo, si desea importar el módulo a otro script:

import important

En la importación, do_importantse llamaría a la función, por lo que probablemente comentaría su llamada a la función do_important(), en la parte inferior.

# do_important() # I must remember to uncomment to execute this!

Y luego tendrá que recordar si ha comentado o no su llamada a la función de prueba. Y esta complejidad adicional significaría que es probable que lo olvide, haciendo que su proceso de desarrollo sea más problemático.

Una mejor manera

La __name__variable apunta al espacio de nombres donde sea que esté el intérprete de Python en este momento.

Dentro de un módulo importado, es el nombre de ese módulo.

Pero dentro del módulo primario (o una sesión interactiva de Python, es decir, Read, Eval, Print Loop o REPL del intérprete) está ejecutando todo desde él "__main__".

Entonces, si verifica antes de ejecutar:

if __name__ == "__main__":
    do_important()

Con lo anterior, su código solo se ejecutará cuando lo esté ejecutando como módulo principal (o lo llame intencionalmente desde otro script).

Una mejor manera

Sin embargo, hay una manera pitónica de mejorar esto.

¿Qué sucede si queremos ejecutar este proceso de negocio desde fuera del módulo?

Si ponemos el código que queremos ejercitar a medida que desarrollamos y probamos una función como esta y luego hacemos nuestra comprobación '__main__'inmediatamente después:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()

Ahora tenemos una función final para el final de nuestro módulo que se ejecutará si ejecutamos el módulo como módulo principal.

Permitirá que el módulo y sus funciones y clases se importen a otros scripts sin ejecutar la mainfunción, y también permitirá que se llame al módulo (y sus funciones y clases) cuando se ejecute desde un '__main__'módulo diferente , es decir

import important
important.main()

Este modismo también se puede encontrar en la documentación de Python en una explicación del __main__módulo. Ese texto dice:

Este módulo representa el alcance (por lo demás anónimo) en el que se ejecuta el programa principal del intérprete: los comandos se leen desde la entrada estándar, desde un archivo de script o desde un mensaje interactivo. Es este entorno en el que la estrofa idiomática de "secuencia de comandos condicional" hace que se ejecute una secuencia de comandos:

if __name__ == '__main__':
    main()
Aaron Hall
fuente
125

if __name__ == "__main__"es la parte que se ejecuta cuando el script se ejecuta desde (digamos) la línea de comandos usando un comando como python myscript.py.

Harley Holcombe
fuente
2
¿Por qué un archivo helloworld.pycon solo print("hello world")en él puede ejecutarse con comando python helloworld.pyincluso cuando no hay if __name__ == "__main__"?
hi15
83

¿Qué if __name__ == "__main__":hacer?

__name__es una variable global (en Python, global en realidad significa en el nivel del módulo ) que existe en todos los espacios de nombres. Suele ser el nombre del módulo (comostr tipo).

Sin embargo, como el único caso especial, en cualquier proceso de Python que ejecute, como en mycode.py:

python mycode.py

el espacio de nombres global de otra forma anónima se le asigna el valor de '__main__'su __name__.

Por lo tanto, incluyendo las líneas finales.

if __name__ == '__main__':
    main()
  • al final de tu script mycode.py,
  • cuando es el módulo primario de punto de entrada que se ejecuta mediante un proceso de Python,

hará mainque se ejecute la función definida de forma exclusiva de su script .

Otro beneficio de usar esta construcción: también puede importar su código como módulo en otro script y luego ejecutar la función principal si su programa decide:

import mycode
# ... any amount of other code
mycode.main()
Aaron Hall
fuente
72

Aquí hay muchas opiniones diferentes sobre la mecánica del código en cuestión, el "Cómo", pero para mí nada de eso tenía sentido hasta que entendí el "Por qué". Esto debería ser especialmente útil para los nuevos programadores.

Tome el archivo "ab.py":

def a():
    print('A function in ab file');
a()

Y un segundo archivo "xy.py":

import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()

¿Qué está haciendo realmente este código?

Cuando ejecutas xy.py, tú import ab. La declaración de importación ejecuta el módulo inmediatamente en la importación, por lo que ablas operaciones se ejecutan antes que el resto de xy. Una vez terminado con ab, continúa con xy.

El intérprete realiza un seguimiento de con qué scripts se están ejecutando __name__. Cuando ejecuta un script, sin importar cómo lo haya llamado, el intérprete lo llama "__main__", convirtiéndolo en el script maestro o 'home' al que se devuelve después de ejecutar un script externo.

Cualquier otra secuencia de comandos que se llame desde esta "__main__"secuencia de comandos se le asigna su nombre de archivo como su __name__(por ejemplo, __name__ == "ab.py"). Por lo tanto, la línea if __name__ == "__main__":es la prueba del intérprete para determinar si está interpretando / analizando el script 'inicial' que se ejecutó inicialmente, o si está mirando temporalmente a otro script (externo). Esto le da flexibilidad al programador para que el script se comporte de manera diferente si se ejecuta directamente frente a una llamada externa.

Pasemos por el código anterior para comprender lo que está sucediendo, centrándonos primero en las líneas no indentadas y el orden en que aparecen en los scripts. Recuerde que los defbloques de función o no hacen nada solos hasta que se los llama. Lo que el intérprete podría decir si murmurara para sí mismo:

  • Abra xy.py como el archivo 'home'; llámalo "__main__"en la __name__variable.
  • Importar y abrir archivo con el __name__ == "ab.py".
  • Oh, una función. Recordaré eso.
  • Ok, funcion a(); Acabo de enterarme de eso. Imprimiendo ' Una función en un archivo ab '.
  • Fin del documento; de vuelta a "__main__"!
  • Oh, una función. Recordaré eso.
  • Otro.
  • Función x(); ok, imprimiendo ' tarea periférica: podría ser útil en otros proyectos '.
  • ¿Qué es esto? Una ifdeclaración Bueno, la condición se ha cumplido (la variable __name__se ha establecido en "__main__"), así que ingresaré a la main()función e imprimiré ' función principal: aquí es donde está la acción '.

Las dos líneas inferiores significan: "Si este es el "__main__"script o 'home', ejecute la función llamadamain() ". Es por eso que verá un def main():bloque arriba, que contiene el flujo principal de la funcionalidad del script.

¿Por qué implementar esto?

¿Recuerdas lo que dije antes sobre las declaraciones de importación? Cuando importa un módulo, no solo lo 'reconoce' y espera más instrucciones: en realidad ejecuta todas las operaciones ejecutables contenidas en el script. Entonces, poner la carne de tu guión en elmain() función lo pone en cuarentena de manera efectiva, aislándolo para que no se ejecute de inmediato cuando lo importa otro script.

Nuevamente, habrá excepciones, pero la práctica común es que main()generalmente no se llama externamente. Entonces quizás se esté preguntando una cosa más: si no estamos llamandomain() , ¿por qué estamos llamando al guión? Esto se debe a que muchas personas estructuran sus scripts con funciones independientes que están diseñadas para ejecutarse independientemente del resto del código en el archivo. Más tarde se les llama en otro lugar del cuerpo del guión. Lo que me lleva a esto:

Pero el código funciona sin él.

Si, eso es correcto. Estas funciones separadas se pueden invocar desde un script en línea que no está contenido dentro de unmain() función. Si está acostumbrado (como lo estoy yo, en mis primeras etapas de aprendizaje de programación) a crear scripts en línea que hagan exactamente lo que necesita, e intentará resolverlo nuevamente si alguna vez necesita esa operación nuevamente. Bueno, no estás acostumbrado a este tipo de estructura interna de tu código, porque es más complicado de construir y no es tan intuitivo de leer.

Pero ese es un script que probablemente no puede tener sus funciones llamadas externamente, porque si lo hiciera comenzaría a calcular y asignar variables inmediatamente. Y es probable que si intentas reutilizar una función, tu nuevo script esté lo suficientemente relacionado con el anterior como para que haya variables conflictivas.

Al dividir las funciones independientes, obtienes la capacidad de reutilizar tu trabajo anterior al llamarlas a otro script. Por ejemplo, "example.py" podría importar "xy.py" y llamar x(), haciendo uso de la función 'x' de "xy.py". (Tal vez es capitalizar la tercera palabra de una cadena de texto dada; crear una matriz NumPy a partir de una lista de números y cuadrarlos; o reducir una superficie 3D. Las posibilidades son ilimitadas).

(Como comentario aparte, esta pregunta contiene una respuesta de @kindall que finalmente me ayudó a comprender: el por qué, no el cómo. Lamentablemente, se ha marcado como un duplicado de esta , lo que creo que es un error).

joechoj
fuente
52

Cuando hay ciertas declaraciones en nuestro módulo ( M.py) que queremos que se ejecute cuando se ejecute como principal (no importado), podemos colocar esas declaraciones (casos de prueba, declaraciones impresas) debajo de este ifbloque.

De forma predeterminada (cuando el módulo se ejecuta como principal, no importado), la __name__variable se establece en "__main__", y cuando se importará, la __name__variable obtendrá un valor diferente, probablemente el nombre del módulo ( 'M'). Esto es útil para ejecutar diferentes variantes de módulos juntos, y separar sus declaraciones de entrada y salida específicas y también si hay casos de prueba.

En resumen , use este if __name__ == "main"bloque ' ' para evitar que se ejecute (cierto) código cuando se importa el módulo.

Nabeel Ahmed
fuente
43

En pocas palabras, __name__ es una variable definida para cada script que define si el script se está ejecutando como módulo principal o si se está ejecutando como un módulo importado.

Entonces si tenemos dos guiones;

#script1.py
print "Script 1's name: {}".format(__name__)

y

#script2.py
import script1
print "Script 2's name: {}".format(__name__)

El resultado de ejecutar script1 es

Script 1's name: __main__

Y el resultado de ejecutar script2 es:

Script1's name is script1
Script 2's name: __main__

Como puede ver, __name__nos dice qué código es el módulo 'principal'. Esto es genial, porque puede escribir código y no tener que preocuparse por problemas estructurales como en C / C ++, donde, si un archivo no implementa una función 'principal', entonces no puede compilarse como un ejecutable y si lo hace, entonces no puede usarse como biblioteca.

Supongamos que escribe un script de Python que hace algo grandioso e implementa una gran cantidad de funciones que son útiles para otros fines. Si quiero usarlos, puedo importar su script y usarlos sin ejecutar su programa (dado que su código solo se ejecuta dentro del if __name__ == "__main__":contexto). Mientras que en C / C ++ tendría que dividir esas piezas en un módulo separado que luego incluye el archivo. Imagine la situación a continuación;

Importación complicada en C

Las flechas son enlaces de importación. Para tres módulos que intentan incluir el código de los módulos anteriores, hay seis archivos (nueve, contando los archivos de implementación) y cinco enlaces. Esto hace que sea difícil incluir otro código en un proyecto en C a menos que se compile específicamente como una biblioteca. Ahora imagínelo para Python:

Importación elegante en Python

Usted escribe un módulo, y si alguien quiere usar su código, simplemente lo importa y la __name__variable puede ayudar a separar la parte ejecutable del programa de la parte de la biblioteca.

redbandit
fuente
2
La ilustración de C / C ++ es incorrecta: 3 veces el mismo nombre de unidad ( archivo1 ).
Wolf
40

Veamos la respuesta de una manera más abstracta:

Supongamos que tenemos este código en x.py:

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

Los bloques A y B se ejecutan cuando estamos en ejecución x.py.

Pero solo el bloque A (y no B) se ejecuta cuando estamos ejecutando otro módulo, y.pypor ejemplo, en el que x.pyse importa y el código se ejecuta desde allí (como cuando x.pyse llama a una función en y.py).

Alisa
fuente
1
No pude editar la publicación (mínimo 6 caracteres si se requiere un cambio). La línea 14 tiene 'xy' en lugar de 'x.py'.
Aprendiendo
35

Cuando ejecuta Python de forma interactiva, a la __name__variable local se le asigna un valor de __main__. Del mismo modo, cuando ejecuta un módulo Python desde la línea de comandos, en lugar de importarlo a otro módulo, a su __name__atributo se le asigna un valor __main__, en lugar del nombre real del módulo. De esta manera, los módulos pueden ver su propio __name__valor para determinar por sí mismos cómo se están utilizando, ya sea como soporte para otro programa o como la aplicación principal ejecutada desde la línea de comandos. Por lo tanto, el siguiente idioma es bastante común en los módulos de Python:

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.
Zain
fuente
34

Considerar:

if __name__ == "__main__":
    main()

Comprueba si el __name__atributo del script Python es "__main__". En otras palabras, si el programa en sí se ejecuta, el atributo será __main__, por lo que se ejecutará el programa (en este caso, la main()función).

Sin embargo, si un módulo usa su script Python if, se ejecutará cualquier código fuera de la instrucción, por lo queif \__name__ == "\__main__" se usa solo para verificar si el programa se usa como módulo o no y, por lo tanto, decide si ejecutar el código.

Larry
fuente
parece que ha pasado demasiado tiempo para escribir la respuesta luminosa +1
snr
27

Antes de explicar algo al respecto if __name__ == '__main__', es importante comprender qué __name__es y qué hace.

¿Qué es __name__?

__name__es un DunderAlias : puede considerarse como una variable global (accesible desde módulos) y funciona de manera similar a global.

Es una cadena (global como se mencionó anteriormente) como lo indica type(__name__)(cediendo <class 'str'>), y es un estándar incorporado para las versiones Python 3 y Python 2 .

Dónde:

No solo se puede usar en scripts, sino que también se puede encontrar tanto en el intérprete como en los módulos / paquetes.

Interprete:

>>> print(__name__)
__main__
>>>

Guión:

test_file.py :

print(__name__)

Resultando en __main__

Módulo o paquete:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

Resultando en somefile

Tenga en cuenta que cuando se usa en un paquete o módulo, __name__toma el nombre del archivo. La ruta del módulo real o la ruta del paquete no se proporciona, pero tiene su propio DunderAlias __file__, que lo permite.

Debería ver que, dónde __name__, dónde está el archivo principal (o programa) siempre devolverá__main__ , y si es un módulo / paquete, o cualquier cosa que se ejecute con algún otro script de Python, devolverá el nombre del archivo donde está se originó a partir de.

Práctica:

Ser una variable significa que su valor puede sobrescribirse ("can" no significa "debería"), sobrescribir el valor de __name__dará como resultado una falta de legibilidad. Así que no lo hagas, por ningún motivo. Si necesita una variable, defina una nueva variable.

Siempre se supone que el valor de __name__ser__main__ o el nombre del archivo. Una vez más, cambiar este valor predeterminado causará más confusión de que será bueno, causando problemas más adelante.

ejemplo:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

Se considera una buena práctica en general incluir los if __name__ == '__main__'scripts en.

Ahora para responder if __name__ == '__main__':

Ahora sabemos el comportamiento de __name__ cosas se vuelve más claro:

Una ifes una instrucción de control de flujo que contiene el bloque de código que se ejecutará si el valor dado es verdadero. Hemos visto que __name__puede tomar cualquiera __main__ o el nombre del archivo desde el que se importó.

Esto significa que si __name__es igual a, __main__entonces el archivo debe ser el archivo principal y en realidad debe estar ejecutándose (o es el intérprete), no un módulo o paquete importado al script.

Si efectivamente __name__toma el valor de __main__lo que esté en ese bloque de código, se ejecutará.

Esto nos dice que si el archivo que se está ejecutando es el archivo principal (o si se está ejecutando directamente desde el intérprete), esa condición debe ejecutarse. Si es un paquete, entonces no debería, y el valor no será __main__.

Módulos:

__name__ también se puede usar en módulos para definir el nombre de un módulo

Variantes:

También es posible hacer otras cosas, menos comunes pero útiles __name__, algunas que mostraré aquí:

Ejecutar solo si el archivo es un módulo o paquete:

if __name__ != '__main__':
    # Do some useful things 

Ejecutando una condición si el archivo es el principal y otra si no lo es:

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

También puede usarlo para proporcionar funciones / utilidades de ayuda ejecutables en paquetes y módulos sin el uso complejo de bibliotecas.

También permite ejecutar módulos desde la línea de comandos como scripts principales, lo que también puede ser muy útil.

Simón
fuente
25

Creo que es mejor romper la respuesta en profundidad y en palabras simples:

__name__: Cada módulo en Python tiene un atributo especial llamado __name__ . Es una variable incorporada que devuelve el nombre del módulo.

__main__: Al igual que otros lenguajes de programación, Python también tiene un punto de entrada de ejecución, es decir, main. '__main__' es el nombre del ámbito en el que se ejecuta el código de nivel superior . Básicamente, tiene dos formas de usar un módulo de Python: ejecutarlo directamente como un script o importarlo. Cuando un módulo se ejecuta como un script, __name__se establece en __main__.

Por lo tanto, el valor del __name__atributo se establece __main__cuando el módulo se ejecuta como el programa principal. De lo contrario, el valor de __name__ se establece para contener el nombre del módulo.

Inconnu
fuente
23

Es especial para cuando se llama a un archivo Python desde la línea de comandos. Esto normalmente se usa para llamar a una función "main ()" o ejecutar otro código de inicio apropiado, como el manejo de argumentos de línea de comandos, por ejemplo.

Se podría escribir de varias maneras. Otro es:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

No digo que debas usar esto en el código de producción, pero sirve para ilustrar que no hay nada "mágico" if __name__ == '__main__'. Es una buena convención para invocar una función principal en archivos Python.

Prof. Falken contrato incumplido
fuente
77
Consideraría esta mala forma ya que estás 1) confiando en los efectos secundarios y 2) abusando and. andse usa para verificar si dos declaraciones booleanas son verdaderas. Como no está interesado en el resultado del and, una ifdeclaración comunica más claramente sus intenciones.
jpmc26
8
Dejando a un lado la pregunta de si explotar el comportamiento de cortocircuito de los operadores booleanos como mecanismo de control de flujo es un mal estilo o no, el mayor problema es que esto no responde a la pregunta en absoluto .
Mark Amery
@ Mark Amery jaja, sheesh, ahora sí. 😊
contrato del Prof. Falken incumplió el
19

El sistema (intérprete de Python) proporciona una serie de variables para los archivos fuente (módulos). Puede obtener sus valores en cualquier momento que desee, así que, centrémonos en la variable / atributo __name__ :

Cuando Python carga un archivo de código fuente, ejecuta todo el código que se encuentra en él. (Tenga en cuenta que no llama a todos los métodos y funciones definidos en el archivo, pero sí los define).

Sin embargo, antes de que el intérprete ejecute el archivo de código fuente, define algunas variables especiales para ese archivo; __name__ es una de esas variables especiales que Python define automáticamente para cada archivo de código fuente.

Si Python está cargando este archivo de código fuente como el programa principal (es decir, el archivo que ejecuta), establece la variable especial __name__ para que este archivo tenga un valor "__main__" .

Si esto se importa desde otro módulo, __name__ se establecerá con el nombre de ese módulo.

Entonces, en su ejemplo en parte:

if __name__ == "__main__":
   lock = thread.allocate_lock()
   thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
   thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

significa que el bloque de código:

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

se ejecutará solo cuando ejecute el módulo directamente; el bloque de código no se ejecutará si otro módulo lo está llamando / importando porque el valor de __name__ no será igual a " main " en esa instancia en particular.

Espero que esto ayude.

codewizard
fuente
17

if __name__ == "__main__": es básicamente el entorno de script de nivel superior, y especifica el intérprete que ('Tengo la máxima prioridad para ejecutar primero').

'__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.

if __name__ == "__main__":
    # Execute only if run as a script
    main()
El Gr8 Adakron
fuente
17

He estado leyendo mucho a lo largo de las respuestas en esta página. Yo diría, si sabes la cosa, seguro que entenderás esas respuestas, de lo contrario, todavía estás confundido.

Para ser breve, necesita conocer varios puntos:

  1. import a la acción realmente ejecuta todo lo que se puede ejecutar en "a"

  2. Debido al punto 1, es posible que no desee que todo se ejecute en "a" al importarlo

  3. Para resolver el problema en el punto 2, Python le permite poner una verificación de condición

  4. __name__es una variable implícita en todos los .pymódulos; cuando a.pyse importa, el valor de __name__del a.pymódulo se establece en su nombre de archivo " a"; cuando a.pyse ejecuta directamente usando " python a.py", lo que significa que a.pyes el punto de entrada, entonces el valor __name__del a.pymódulo se establece en una cadena__main__

  5. Basado en el mecanismo de cómo Python establece la variable __name__para cada módulo, ¿sabe cómo lograr el punto 3? La respuesta es bastante fácil, ¿verdad? Ponga una condición si: if __name__ == "__main__": ...; incluso puede ponerlo si __name__ == "a"depende de su necesidad funcional

¡Lo importante que tiene Python es especial en el punto 4! El resto es solo lógica básica.

Jack
fuente
1
Sí, el punto 1 es vital para entender. A partir de eso, se hace evidente la necesidad de este mecanismo.
Eureka
16

Considerar:

print __name__

La salida para lo anterior es __main__.

if __name__ == "__main__":
  print "direct method"

La declaración anterior es verdadera e imprime "método directo" . Supongamos que si importaron esta clase en otra clase, no imprime "método directo" porque, al importar, se establecerá __name__ equal to "first model name".

Janarthanan Ramu
fuente
14

Puede hacer que el archivo se pueda usar como un script y como un módulo importable .

fibo.py (un módulo llamado 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]))

Referencia: https://docs.python.org/3.5/tutorial/modules.html

kgf3JfUtW
fuente
14

La razón por

if __name__ == "__main__":
    main()

es principalmente para evitar los problemas de bloqueo de importación que surgirían al importar el código directamente . Desea main()ejecutarse si su archivo fue invocado directamente (esa es la__name__ == "__main__" caso), pero si su código fue importado, entonces el importador debe ingresar su código desde el módulo principal verdadero para evitar problemas de bloqueo de importación.

Un efecto secundario es que inicia sesión automáticamente en una metodología que admite múltiples puntos de entrada. Puede ejecutar su programa utilizando main()como punto de entrada, pero no tiene que hacerlo . Mientras setup.pyespera main(), otras herramientas usan puntos de entrada alternativos. Por ejemplo, para ejecutar su archivo como un gunicornproceso, defina una app()función en lugar de a main(). Al igual que con setup.py, gunicornimporta su código para que no quiera que haga nada mientras se importa (debido al problema de bloqueo de importación).

nube_personal
fuente
3
Es bueno aprender sobre el bloqueo de importación . ¿Podría explicar por favor iniciar sesión en una metodología que [...] separe un poco más?
Wolf
1
@ Wolf: Claro. He agregado algunas oraciones sobre la metodología de múltiples puntos de entrada.
personal_cloud
11

Esta respuesta es para programadores Java que aprenden Python. Cada archivo Java generalmente contiene una clase pública. Puedes usar esa clase de dos maneras:

  1. Llame a la clase desde otros archivos. Solo tiene que importarlo en el programa de llamadas.

  2. Ejecute la clase de forma independiente, con fines de prueba.

Para el último caso, la clase debe contener un método main () vacío público estático. En Python, este propósito lo cumple la etiqueta globalmente definida '__main__'.

Raja
fuente
11

El código debajo if __name__ == '__main__': solo se ejecutará si el módulo se invoca como un script .

Como ejemplo, considere el siguiente módulo my_test_module.py:

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

Primera posibilidad: importar my_test_module.pyen otro módulo

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

Ahora si invocas main.py:

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

Tenga en cuenta que solo se ejecuta la print()instrucción de nivel superior en my_test_module.


2da posibilidad: invocar my_test_module.pycomo script

Ahora, si se ejecuta my_test_module.pycomo un script de Python, ambas print()declaraciones se ejecutarán:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'
Giorgos Myrianthous
fuente
10

Cada módulo en python tiene un atributo llamado __name__. El valor del __name__ atributo es __main__ cuando el módulo se ejecuta directamente, como python my_module.py. De lo contrario (como cuando dice import my_module), el valor de __name__ es el nombre del módulo.

Pequeño ejemplo para explicar en breve.

#Script test.py

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()

Podemos ejecutar esto directamente como

python test.py  

Salida

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

Ahora supongamos que llamamos al script anterior desde otro script

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

Cuando ejecutas esto

python external_calling.py

Salida

42
I am inside hello_world
test

Por lo tanto, lo anterior es que explica por sí mismo cuando se llama a prueba desde otro script, si el rizo __name__en test.pyno ejecutará.

Rishi Bansal
fuente
6

Si este archivo .py es importado por otros archivos .py, el código bajo "la instrucción if" no se ejecutará.

Si este .py se ejecuta python this_py.pybajo shell, o se hace doble clic en Windows. se ejecutará el código debajo de "la declaración if".

Por lo general, se escribe para pruebas.

pah8J
fuente
6

Si el intérprete de Python ejecuta un módulo en particular, __name__la variable global tendrá valor"__main__"

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

Cuando ejecutas este script , puedes verme

una

Si importa este archivo, diga A al archivo B y ejecute el archivo B, entonces if __name__ == "__main__"en el archivo A se convierte en falso, por lo que se imprime No puede verme

si

Nikil Munireddy
fuente
5

Todas las respuestas han explicado más o menos la funcionalidad. Pero proporcionaré un ejemplo de su uso que podría ayudar a aclarar aún más el concepto.

Suponga que tiene dos archivos Python, a.py y b.py. Ahora, a.py importa b.py. Ejecutamos el archivo a.py, donde primero se ejecuta el código "import b.py". Antes de que se ejecute el resto del código a.py, el código del archivo b.py debe ejecutarse por completo.

En el código b.py hay un código que es exclusivo de ese archivo b.py y no queremos ningún otro archivo (que no sea el archivo b.py) que haya importado el archivo b.py para ejecutarlo.

Entonces eso es lo que esta línea de código verifica. Si el archivo principal (es decir, b.py) ejecuta el código, que en este caso no lo es (a.py es el archivo principal en ejecución), solo se ejecuta el código.

preetika mondal
fuente
4

Crea un archivo, a.py :

print(__name__) # It will print out __main__

__name__siempre es igual a __main__cuando ese archivo se ejecuta directamente mostrando que este es el archivo principal.

Cree otro archivo, b.py , en el mismo directorio:

import a  # Prints a

Ejecutarlo. Imprimirá un , es decir, el nombre del archivo que se importa .

Entonces, para mostrar dos comportamientos diferentes del mismo archivo , este es un truco de uso común:

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly
DARK_C0D3R
fuente
4

if name == ' main ':

Vemos si con __name__ == '__main__':bastante frecuencia.

Comprueba si se está importando un módulo o no.

En otras palabras, el código dentro del ifbloque se ejecutará solo cuando el código se ejecute directamente. Aquí directlysignificanot imported .

Veamos qué hace usando un código simple que imprime el nombre del módulo:

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

Si ejecutamos el código directamente python test.py, el nombre del módulo es __main__:

call test()
test module name=__main__
Ali Hallaji
fuente
4

Simplemente, es el punto de entrada para ejecutar el archivo, como la mainfunción en el lenguaje de programación C.

Mohammed Awney
fuente
8
Esta respuesta supone que el OP (o cualquier usuario con una pregunta similar) está familiarizado con C y sabe qué es un punto de entrada.
arredond
1
Esta respuesta también supone que no tiene lugar ningún código (aparte de las definiciones sin efectos secundarios) antes del if __name__ == "__main__"bloque. Técnicamente, la parte superior del script ejecutado es el punto de entrada del programa.
Charlie Harding