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




14 Answers

Cuando el intérprete de Python lee un archivo de origen, 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 programa principal, configura la variable __name__ especial para que tenga un valor "__main__" . Si este archivo se está importando de otro módulo, __name__ se configurará al nombre del módulo.

En el caso de su script, supongamos que se está ejecutando como la función principal, por ejemplo, usted dijo algo como

python threading_example.py

en la linea de comando Después de configurar las variables especiales, ejecutará la declaración de import y cargará esos módulos. A continuación, evaluará el bloque def , creando un objeto de función y creando una variable llamada myfunction que apunta al objeto de función. Luego leerá la instrucción if y verá que __name__ es igual a "__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 (un archivo .py ) donde se puede ejecutar directamente. Alternativamente, también se puede importar y usar en otro módulo. Al realizar la comprobación principal, puede hacer que ese código solo se ejecute cuando desee ejecutar el módulo como un programa y no ejecutarlo cuando alguien solo quiera importar su módulo y llamar a sus propias funciones.

Vea esta página para algunos detalles adicionales.

Nota (por Stainsor): Si coloca el código antes de las definiciones de la función, se ejecutará antes que main.

print("This code executes before main.") 

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

def functionB():
    print("Function B")

if __name__ == '__main__':
    functionA()
    functionB()

Si este módulo es de hecho principal, este código resulta en:

This code executes before main. 
Function A 
Function B

Si este módulo no es el principal, obtienes:

This code executes before main. 
español if

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



La explicación más simple para la variable __name__ (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__

Al ejecutarlos obtendrás 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 en "__main__" .




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 .




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

Toma 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 , import ab . La declaración de importación ejecuta el módulo inmediatamente después de la importación, por lo que las operaciones de ab se ejecutan antes del resto de xy . Una vez terminado con ab , continúa con xy .

El intérprete realiza un seguimiento de qué secuencias de comandos se ejecutan con __name__ . Cuando ejecuta un script, no importa cómo lo haya nombrado, el intérprete lo llama "__main__" , lo que lo convierte en el script maestro o "de inicio" al que se vuelve después de ejecutar un script externo.

A cualquier otro script que se llame desde este "__main__" se le asigna su nombre de archivo como __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 guión 'inicial' que se ejecutó inicialmente, o si se está asomando temporalmente a otro guión (externo). Esto le da al programador flexibilidad para que el script se comporte de manera diferente si se ejecuta directamente o se llama externamente.

Revisemos el código anterior para entender lo que está sucediendo, enfocándonos primero en las líneas sin sangría y en el orden en que aparecen en los scripts. Recuerde que los bloques de función, o de def , no hacen nada por sí mismos hasta que se llaman. Lo que el intérprete podría decir si murmurara a sí mismo:

  • Abra xy.py como el archivo 'home'; llámalo "__main__" en la variable __name__ .
  • Importe y abra el archivo con el __name__ == "ab.py" .
  • Oh, una función. Recordaré eso.
  • Ok, funciona a() ; Acabo de aprender 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 declaración if . Bueno, la condición se ha cumplido (la variable __name__ se ha establecido en "__main__" ), por lo que "__main__" en la función main() e imprimiré la función main: aquí es donde está la acción .

Las dos líneas inferiores "__main__" : "Si este es el "__main__" o 'home', ejecute la función llamada main() ". Es por eso que verá un def main(): block up top, 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 instrucciones adicionales, en realidad ejecuta todas las operaciones ejecutables contenidas en el script. Por lo tanto, poner la fuente de su script en la función main() pone en cuarentena de manera efectiva, aislándolo para que no se ejecute inmediatamente cuando se importa con otro script

Nuevamente, habrá excepciones, pero la práctica común es que main() generalmente no recibe llamadas externas. Entonces puede que se esté preguntando una cosa más: si no estamos llamando a main() , ¿por qué estamos llamando al script? Esto se debe a que muchas personas estructuran sus scripts con funciones independientes que están diseñadas para ejecutarse de manera independiente del resto del código del archivo. Luego se les llama en otro lugar en el cuerpo de la secuencia de comandos. Lo que me lleva a esto:

Pero el código funciona sin él.

Sí, eso es correcto. Estas funciones separadas se pueden llamar desde un script en línea que no está contenido dentro de una función main() . Si está acostumbrado (al igual que yo, en mis primeras etapas de aprendizaje de la programación) a crear scripts en línea que hagan exactamente lo que necesita, e intentará averiguarlo de nuevo 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 pueda tener sus funciones llamadas externamente, porque si lo hiciera, inmediatamente comenzaría a calcular y asignar variables. Y lo más probable es que si está intentando reutilizar una función, su nuevo script esté lo suficientemente relacionado con el anterior de que habrá variables en conflicto.

Al dividir las funciones independientes, puede reutilizar su trabajo anterior llamándolos a otro script. Por ejemplo, "example.py" podría importar "xy.py" y llamar a x() , haciendo uso de la función 'x' de "xy.py". (Tal vez esté en mayúscula la tercera palabra de una cadena de texto dada; creando una matriz NumPy a partir de una lista de números y cuadrándolos; o desvirtuando una superficie 3D. Las posibilidades son ilimitadas).

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




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 ejecutamos "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).




Cuando ejecutas Python interactivamente, a la variable __name__ local se le asigna un valor de __main__ . Del mismo modo, cuando ejecuta un módulo de Python desde la línea de comandos, en lugar de importarlo a otro módulo, a su atributo __name__ se le asigna un valor de __main__ , en lugar del nombre real del módulo. De esta manera, los módulos pueden ver su propio valor __name__ 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.



Antes de explicar algo sobre if __name__ == '__main__' es importante entender qué es __name__ y qué hace.

¿Qué es __name__ ?

__name__ es un DunderAlias : se puede considerar como una variable global (accesible desde módulos) y funciona de una manera similar a la global .

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

Dónde:

No solo puede usarse en scripts, sino que también puede encontrarse 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

Observe 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 da, pero tiene su propio DunderAlias __file__ , que permite esto.

Debería ver que, donde __name__ , donde está el archivo principal (o programa) siempre devolverá __main__ , y si es un módulo / paquete, o algo que se esté ejecutando en algún otro script de Python, devolverá el nombre del archivo De donde se ha originado.

Práctica:

Ser una variable significa que su valor se puede sobrescribir ("can" no significa "debería"), sobrescribir el valor de __name__ resultará en una falta de legibilidad. Así que no lo hagas, por ninguna razón. Si necesitas una variable define una nueva variable.

Siempre se asume que el valor de __name__ es __main__ o el nombre del archivo. Una vez más, cambiar este valor predeterminado causará más confusión de que funcionará bien, causando problemas más adelante.

ejemplo:

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

En general, se considera una buena práctica incluir el if __name__ == '__main__' en los scripts.

Ahora para responder if __name__ == '__main__' :

Ahora que sabemos el comportamiento de __name__ cosas se vuelven más claras:

Un if es una sentencia 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 __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 realmente debe estar ejecutándose (o es el intérprete), no un módulo o paquete importado en el script.

Si efectivamente __name__ toma el valor de __main__ entonces cualquier cosa que esté en ese bloque de código se ejecutará.

Esto nos dice que si el archivo en ejecución es el archivo principal (o si 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 con __name__ , algunas de las cuales mostraré aquí:

Ejecutando 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 otro 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 elaborado de las bibliotecas.

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




Creo que es mejor romper la respuesta en profundidad y con 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, su __name__ se establece en __main__ .

Por lo tanto, el valor del atributo __name__ se establece en __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.




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

'__main__' es el nombre del ámbito en el que se ejecuta el código de nivel superior. El __name__ un módulo se establece igual a '__main__' cuando se lee desde una entrada estándar, un script o desde un indicador interactivo.

if __name__ == "__main__":
    # Execute only if run as a script
    main()



Puede hacer que el archivo sea utilizable como un script , así 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




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

Para ser breve, necesitas conocer varios puntos:

  1. import a acción en realidad 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 módulos .py; cuando se importa a.py, el valor de __name__ de un módulo de.py se establece en su nombre de archivo "a"; cuando a.py se ejecuta directamente con "python a.py", lo que significa que a.py es el punto de entrada, entonces el valor de __name__ de un módulo de a.py 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 se puede poner si __name__ == "a"depende de su necesidad funcional.

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




Crea un archivo, a.py :

print(__name__) # It will print out __main__

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

Crea 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 comúnmente usado:

# Code to be run when imported into another python file

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



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

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

  2. Ejecutar la clase independiente, para fines de prueba.

Para el último caso, la clase debe contener un método public static void main (). En Python, este propósito lo cumple la etiqueta definida globalmente '__main__'.




Recientemente, encontré esto mientras creaba una clase en python (aprendizaje profundo) y, a mi entender y de acuerdo con las explicaciones mencionadas anteriormente, elaboraré

__name__=="__main__"

Como a veces construimos una clase en un archivo .py, y definimos muchas funciones dentro de esa clase. pero no queremos procesar todas esas funciones de clase para un solo propósito. por ejemplo, para crear una clase y definir algunas funciones para la creación de datos (archivos .npy), mientras que otras para la carga de datos. así que si definimos

__name__=="__main__"

xxx = class_name ()

xxx.create_data ()

Significa que si llamamos al archivo .py, entonces solo creará datos y no procesará otras funciones de clase. Otras funciones de clase (carga de datos) también pueden ser importadas por otras clases.




Related

python namespaces main python-module idioms