Qué pasa si __name__ == __main__ hacer en Python

if __name__ == __main__ se usa para controlar el comportamiento de nuestro código Python cuando se ejecuta directamente o se importa como un módulo. Este tutorial explica cómo.

Introducción

Es común ver if __name__ == "__main__" en los scripts de Python que encontramos en línea, o uno de los muchos que escribimos nosotros mismos.

¿Por qué usamos esa declaración if cuando ejecutamos nuestros programas de Python? En este artículo, explicamos la mecánica detrás de su uso, las ventajas y dónde se puede utilizar.

El atributo __name__ y el __main__ Scope

El atributo __name__ viene por defecto como uno de los nombres en el alcance local actual. El intérprete de Python agrega automáticamente este valor cuando ejecutamos un script de Python o importamos nuestro código como un módulo.

Pruebe el siguiente comando en su intérprete de Python. Puede descubrir que __name__ pertenece a la lista de atributos en dir():

1
dir()

dir() output

El __name__ en Python es una variable especial que define el nombre de la clase o el módulo actual o el script desde el que se invoca.

Cree una nueva carpeta llamada name_scripts para que podamos escribir algunos scripts para comprender cómo funciona todo esto. En esa carpeta crea un nuevo archivo, script1.py con el siguiente código:

1
print(f'The __name__ from script1 is "{__name__}"')

script1.py output

¡Eso es una bola curva! Esperaríamos que el nombre fuera script1, como nuestro archivo. ¿Qué significa la salida __main__?

De forma predeterminada, cuando se ejecuta un script, el intérprete lee el script y asigna la cadena __main__ a la palabra clave __name__.

Se vuelve aún más interesante cuando el script anterior se importa a otro script. Considere un archivo de Python llamado script2.py con el siguiente código:

1
2
3
import script1  # The print statement gets executed upon import

print(f'The __name__ from script2 is "{__name__}"')

script2.py output

Como puede ver, cuando se ejecuta el script, la salida se muestra como script1, que indica el nombre del script. La instrucción de impresión final está en el ámbito de script2 y cuando se ejecuta, la salida se imprime como: __main__.

Ahora que entendemos cómo Python usa el alcance __name__ y cuándo le da un valor de "__main__", veamos por qué verificamos su valor antes de ejecutar el código.

if __name__ == "__main__" in Action

Usamos la instrucción if para ejecutar bloques de código solo si nuestro programa es el programa principal ejecutado. Esto permite que nuestro programa sea ejecutable por sí mismo, pero amigable con otros módulos de Python que deseen importar alguna funcionalidad sin tener que ejecutar el código.

Considere los siguientes programas de Python:

a) script3.py contiene una función llamada add() que se invoca solo desde el contexto principal.

1
2
3
4
5
6
def add(a, b):
    return a+b


if __name__ == "__main__":
    print(add(2, 3))

Aquí está el resultado cuando se invoca script3.py:

script3.py output

Como el script se ejecutó directamente, la palabra clave __name__ se asigna a __main__, y se ejecuta el bloque de código bajo la condición if __name__ == "__main__".

b) Esto es lo que sucede cuando este fragmento se importa desde script4.py:

1
2
3
import script3

print(f"{script3.__name__}")

script4.py output

El bloque bajo if __name__ == "__main__" de script3.py no se ejecutó, como se esperaba. Esto sucedió porque la palabra clave __name__ ahora se asigna con el nombre del script: script3. Esto se puede verificar mediante la declaración de impresión dada que imprime el valor asignado para la palabra clave __name__.

¿Cómo ayuda __name__ == "__main__" en el desarrollo?

Aquí hay algunos casos de uso para usar esa declaración if al crear su script

  • La prueba es una buena práctica que ayuda no solo a detectar errores, sino también a garantizar que su código se comporte según lo requerido. Los archivos de prueba tienen que importarles una función u objeto. En estos casos, normalmente no queremos que el script se ejecute como módulo principal.
  • Está creando una biblioteca pero le gustaría incluir una demostración u otros casos especiales de tiempo de ejecución para los usuarios. Al usar esta declaración if, los módulos de Python que usan su código como biblioteca no se ven afectados.

Creando un archivo __main__.py para módulos

El punto de tener el bloque if __name__ == "__main__" es obtener la pieza de código bajo la condición de ejecutarse cuando el script está en el alcance __main__. Sin embargo, al crear paquetes en Python, es mejor si el código que se ejecutará bajo el contexto __main__ se escribe en un archivo separado.

Consideremos el siguiente ejemplo: un paquete para realizar cálculos. La estructura de árbol de archivos para tal escenario se puede visualizar como:

1
2
3
4
5
6
7
8
9
calc                 # --> Root directory
├── __main__.py
├── script1.py
├── script2.py
├── script3.py
├── script4.py
└── src              # --> Sub-directory
    ├── add.py
    └── sub.py

La estructura de árbol contiene calc como directorio raíz y un subdirectorio conocido como src. El __main__.py bajo el directorio calc contiene el siguiente contenido:

1
2
3
4
5
6
7
8
from src.add import add
from src.sub import sub

a, b = input("Enter two numbers separated by commas: ").split(',')
a, b = int(a), int(b)

print(f"The sum is: {add(a, b)}")
print(f"The difference is: {sub(a, b)}")

El add.py contiene:

1
2
def add(a, b):
    return a+b

Y sub.py contiene:

1
2
def sub(a, b):
    return a-b

Justo fuera del directorio calc, se puede ejecutar el script y la lógica dentro de __main__.py se ejecuta invocando:

1
python3 calc

script1.py output

Esta estructura también da una apariencia más limpia a la ubicación del espacio de trabajo, la forma en que se organizan los directorios y el punto de entrada se define dentro de un archivo separado llamado __main__.py.

Conclusión

__name__ == "__main__" ejecuta bloques de código solo cuando nuestro script de Python se ejecuta directamente desde un usuario. Esto es poderoso ya que permite que nuestro código tenga un comportamiento diferente cuando se ejecuta como un programa en lugar de importarlo como un módulo.

Al escribir módulos grandes, podemos optar por el enfoque más estructurado de tener un archivo __main__.py para ejecutar un módulo. Para un script independiente, incluir if __name__ == "__main__" es un método más simple para separar la API del programa. ama.

Licensed under CC BY-NC-SA 4.0