Pregunta ¿Qué hace si __name__ == "__main__": do?


Lo que hace el if __name__ == "__main__": ¿hacer?

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

4128
2018-01-07 04:11


origen


Respuestas:


Cuando el intérprete de Python lee un archivo fuente, ejecuta todo el código que se encuentra en él.

Antes de ejecutar el código, definirá algunas variables especiales. Por ejemplo, si el intérprete de Python está ejecutando ese módulo (el archivo de origen) como el programa principal, establece el especial __name__ variable para tener un valor "__main__". Si este archivo se está importando de otro módulo, __name__ se configurará con el nombre del módulo.

En el caso de su script, supongamos que se está ejecutando como la función principal, p. dijiste algo como

python threading_example.py

en la línea de comando. Después de configurar las variables especiales, ejecutará el import declaración y cargar esos módulos. Luego evaluará la def bloquear, crear un objeto de función y crear una variable llamada myfunction eso apunta al objeto de función. Luego leerá el if declaración y ver eso __name__ hace lo mismo "__main__", por lo que ejecutará el bloque que se muestra allí.

Una razón para hacer esto es que a veces se escribe un módulo (una .py archivo) donde se puede ejecutar directamente. Alternativamente, también se puede importar y usar en otro módulo. Al hacer la verificación principal, puede hacer que el código se ejecute solo cuando desea ejecutar el módulo como un programa y no ejecutarlo cuando alguien simplemente quiere importar su módulo y llamar a sus funciones.

Ver esta página para algunos detalles adicionales.


4407
2018-01-07 04:26



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 las clases definidas están bien definidas, pero no se ejecuta ninguno de sus códigos. A diferencia de otros idiomas, no hay main() función que se ejecuta automáticamente - el main() función es implícitamente todo el código en el nivel superior.

En este caso, el código de nivel superior es if bloquear. __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 myscript.py arriba), luego __name__ en cambio, se establece en la cadena "__main__". Por lo tanto, puede probar si su script se está ejecutando directamente o si se está importando por algo más mediante la prueba

if __name__ == "__main__":
    ...

Si su script se está importando a otro módulo, se importarán sus diversas definiciones de funciones y clases y se ejecutará su código de nivel superior, pero el código en el cuerpo entonces del if la cláusula de arriba no se ejecutará ya que la condición no se cumple. 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 invocas al intérprete como

python one.py

La salida será

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

Si tu corres two.py en lugar:

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 one se carga, es __name__ igual "one" en lugar de "__main__".


1403
2018-01-07 04:28



La explicación más simple para el __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 al nombre del módulo.

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

Como puede ver, cuando se ejecuta un archivo, Python establece globals()['__name__'] en este archivo para "__main__".


560
2018-01-07 11:35



Lo que hace el if __name__ == "__main__": ¿hacer?

Para delinear 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, codifique bajo if bloque solo se ejecutará si el módulo es el punto de entrada a su programa.

  • Permite que el código en el módulo sea importable por otros módulos, sin ejecutar el bloque de código debajo de la importación.


¿Porqué necesitamos esto?

Desarrollando y probando su código

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

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

podría Pruebe el módulo agregando esta llamada de la función al final:

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 importación, el do_important se llamaría a la función, por lo que probablemente comentaría su llamada de función, do_important(), en el fondo.

# 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 olvides, haciendo que tu proceso de desarrollo sea más problemático.

Una mejor manera

los __name__ variable apunta al espacio de nombres dondequiera 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, la lectura, evaluación, bucle de impresión o REPL) del intérprete, se está ejecutando todo desde su "__main__".

Entonces, si comprueba antes de ejecutar:

if __name__ == "__main__":
    do_important()

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

Una forma aún mejor

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

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

Si ponemos el código que queremos ejercer a medida que desarrollamos y probamos en una función como esta y luego hacemos nuestro control de '__main__' inmediatamente despues:

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 el módulo principal.

Permitirá que el módulo y sus funciones y clases se importen a otros scripts sin ejecutar el main función, y también permitirá que el módulo (y sus funciones y clases) sean llamados cuando se ejecuta desde un '__main__' módulo, es decir

import important
important.main()

Esta expresión también se puede encontrar en la documentación de Python en una explicación de la __main__ módulo. Ese texto dice:

Este módulo representa el alcance (por lo demás anónimo) en el cual el   se ejecuta el programa principal del intérprete - comandos leídos desde   entrada estándar, desde un archivo de script, o desde un aviso interactivo. Eso   es este entorno en el que la estrofa idiomática "script condicional"   hace que se ejecute un script:

if __name__ == '__main__':
    main()

412
2017-11-23 04:38



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


92
2018-01-07 04:14



Que hace if __name__ == "__main__": ¿hacer?

__name__ es una variable global (en Python, global significa realmente en el nivel de módulo) que existe en todos los espacios de nombres. Por lo general, es el nombre del módulo (como str tipo).

Como el único caso especial, sin embargo, en cualquier proceso de Python que ejecutes, como en mycode.py:

python mycode.py

el espacio de nombres global que de otro modo sería anónimo se le asigna el valor de '__main__' a su __name__.

Por lo tanto, incluyendo las últimas líneas

if __name__ == '__main__':
    main()
  • al final de su script mycode.py,
  • cuando es el módulo principal de punto de entrada ejecutado por un proceso de Python,

hará que el script esté definido de forma única main función para ejecutar.

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

import mycode
# ... any amount of other code
mycode.main()

57
2017-10-14 20:22



Aquí hay muchas tomas 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.

Lleve 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 instrucción de importación ejecuta el módulo inmediatamente en la importación, por lo que abLas operaciones se ejecutan antes del resto de xyes Una vez terminado con ab, continúa con xy.

El intérprete realiza un seguimiento de los scripts que se ejecutan con __name__. Cuando ejecuta un script, sin importar cómo lo haya llamado, el intérprete lo llama "__main__", lo que lo convierte en el script principal o 'home' al que se devuelve después de ejecutar un script externo.

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

Avancemos el código anterior para comprender lo que está sucediendo, centrándonos primero en las líneas no perdidas y el orden en que aparecen en los guiones. Recuerde esa función - o def - Los bloques no hacen nada por sí mismos hasta que se llaman. Lo que el intérprete podría decir si murmurara para sí mismo:

  • Abra xy.py como el archivo 'home'; llámalo "__main__" en el __name__ variable.
  • Importar y abrir archivo con el __name__ == "ab.py".
  • Oh, una función. Recordaré eso.
  • Ok, función a(); Me acabo de enterar de eso. Impresión 'Una función en archivo ab'.
  • Fin del documento; de regreso "__main__"!
  • Oh, una función. Recordaré eso.
  • Otro.
  • Función x(); ok, imprimiendotarea periférica: podría ser útil en otros proyectos'.
  • ¿Qué es esto? Un if declaración. Bueno, la condición se ha cumplido (la variable __name__ha sido configurado para "__main__"), entonces entraré al main() función e impresión 'función principal: aquí es donde está la acción'.

Las dos líneas inferiores significan: "Si este es el "__main__" o script 'home', ejecuta la función llamada main()". Es por eso que verás un def main(): bloquear 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, sino que ejecuta todas las operaciones ejecutables contenidas en el script. Entonces, poniendo la carne de tu script en el main() la función efectivamente lo pone en cuarentena, poniéndolo aislado para que no se ejecute inmediatamente cuando lo importe otro script.

De nuevo, habrá excepciones, pero la práctica común es que main() por lo general no se llama externamente. Entonces, te estarás preguntando una cosa más: si no estamos llamando main(), ¿por qué llamamos el guión? 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. Posteriormente, se les llama a otro lugar en el cuerpo del guión. Lo que me lleva a esto:

Pero el código funciona sin él

Si, eso es correcto Estas funciones separadas poder ser llamado desde un script en línea que no está contenido dentro de un main() función. Si está acostumbrado (como lo estoy yo, en mis primeros pasos de programación) a crear scripts en línea que hagan exactamente lo que necesita, y tratará de resolverlo nuevamente si alguna vez necesita esa operación nuevamente. Bueno, no está acostumbrado a este tipo de estructura interna en su código, porque es más complicado de construir y no es tan intuitivo de leer.

Pero ese es un script que probablemente no pueda tener sus funciones llamadas externamente, porque si lo hiciera, comenzaría inmediatamente a calcular y asignar variables. Y lo más probable es que si intenta volver a utilizar una función, su nueva secuencia de comandos esté relacionada con la anterior de forma tal que haya variables conflictivas.

Al dividir las funciones independientes, obtiene la capacidad de reutilizar su trabajo anterior llamándolos 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 está capitalizando la tercera palabra de una cadena de texto dada, creando una matriz NumPy a partir de una lista de números y cuadratándola, o desdibujando una superficie 3D. Las posibilidades son ilimitadas).

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


47
2017-09-29 04:33



Cuando hay ciertas declaraciones en nuestro módulo (M.py) queremos que se ejecute cuando se ejecutará como main (no importado), podemos colocar esas declaraciones (test-cases, print statements) debajo de este ifbloquear.

Como por defecto (cuando el módulo se ejecuta como principal, no importado) el __name__ la variable está configurada para "__main__"y cuando se importará __name__ variable obtendrá un valor diferente, probablemente el nombre del módulo ('M') Esto es útil para ejecutar juntas diferentes variantes de un módulo, y separar sus declaraciones de entrada y salida específicas y también si hay casos de prueba.

En breve, utilizar esta 'if __name__ == "main" 'bloquear para evitar que se ejecute (cierto) código cuando se importa el módulo.


39
2018-04-03 14:09



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 ejecutando "x.py".

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


32
2018-01-20 17:48