python if '__ - ¿Qué hace si __name__ == “__main__”: hazlo?



13 Answers

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

En este caso, el código de nivel superior es un bloque if . __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), entonces __name__ se establece en la cadena "__main__" . Por lo tanto, puede probar si su script se ejecuta directamente o si es importado por otra cosa probando

if __name__ == "__main__":
    ...

Si su script 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 cláusula if arriba no se ejecutará como 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 ejecuta two.py en two.py 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 se carga el módulo one , su __name__ es igual a "one" lugar de "__main__" .

__' () '__main__'

¿Qué 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))



¿Qué 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, el código bajo el bloque if 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?

Desarrollar y probar su código

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

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

Puede probar el módulo agregando 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, se do_important función do_important , por lo que probablemente comentarías tu llamada de 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 variable __name__ apunta al espacio de nombres donde quiera que se encuentre 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, la evaluación, el ciclo de impresión o el REPL del intérprete) está ejecutando todo desde su "__main__" .

Así que si chequeas antes de ejecutar:

if __name__ == "__main__":
    do_important()

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

Una manera aún mejor

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

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

Si colocamos el código que queremos ejercer a medida que desarrollamos y probamos en una función como esta y luego hacemos nuestro chequeo para '__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 el módulo principal.

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

import important
important.main()

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

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

if __name__ == '__main__':
    main()



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

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

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 anónimo se asigna el valor de '__main__' a su __name__ .

Así, incluidas las líneas finales.

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

hará que se ejecute la función main definida de forma única de su script.

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 cuando su programa decida:

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



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

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

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




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

Así que 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__)

La salida de la ejecución de script1 es

Script 1's name: __main__

Y la salida de la ejecución de 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 simplemente puede escribir código y no tiene que preocuparse por problemas estructurales como en C / C ++, donde, si un archivo no implementa una función 'principal', no se puede compilar como un ejecutable y si lo hace, no se puede utilizar como una biblioteca.

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

Las flechas son enlaces de importación. Para cada 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 de C a menos que se compile específicamente como una biblioteca. Ahora imagínalo para Python:

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




Considerar:

if __name__ == "__main__":
    main()

Comprueba si el atributo __name__ de la secuencia de comandos de Python es "__main__" . En otras palabras, si el programa se ejecuta, el atributo será __main__ , por lo que el programa se ejecutará (en este caso, la función main() ).

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




Hay una serie de variables que el sistema (intérprete de Python) proporciona para los archivos de origen (módulos). Puede obtener sus valores en cualquier momento que desee, por lo tanto, permítanos concentrarnos 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), entonces establece la variable __name__ especial para que este archivo tenga un valor "__main__" .

Si se está importando desde otro módulo, __name__ se configurará al nombre de ese módulo.

Entonces, en tu 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 ejecutes 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.




Es especial para cuando se llama a un archivo Python desde la línea de comandos. Normalmente se usa para llamar a una función "main ()" o para ejecutar otro código de inicio apropiado, como el manejo de argumentos de la 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 estoy diciendo que debas usar esto en el código de producción, pero sirve para ilustrar que no hay nada "mágico" acerca de if __name__ == '__main__' . Es una buena convención para invocar una función principal en archivos Python.




La razón por

if __name__ == "__main__":
    main()

es principalmente para evitar los problemas de bloqueo de importación que surgirían si se importara el código directamente . Desea ejecutar main() si su archivo fue invocado directamente (ese es el caso __name__ == "__main__" ), pero si su código fue importado, el importador debe ingresar su código desde el verdadero módulo principal 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 usando main() como punto de entrada, pero no tiene que hacerlo . Mientras que setup.py espera main() , otras herramientas usan puntos de entrada alternativos. Por ejemplo, para ejecutar su archivo como un proceso gunicorn , define una función app() lugar de main() . Al igual que con setup.py , gunicorn importa tu código para que no desees hacer nada mientras se importa (debido al problema de bloqueo de importación).




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, establecerá __name__ equal to "firstmodel name" .




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

Si este .py se ejecuta python this_py.pybajo shell o se hace doble clic en Windows. se ejecutará el código bajo "la sentencia if".

Por lo general, se escribe para la prueba.




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

Supongamos 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 en el archivo b.py debe ejecutarse completamente.

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

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




si nombre == ' principal ':

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

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

En otras palabras, el código dentro del ifbloque se ejecutará solo cuando el código se ejecute directamente. Aquí directlysignifica not 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 a través de python test.py, el nombre del módulo es __main__:

call test()
test module name=__main__



Related