Esta es una de las primeras cosas extrañas que te puedes encontrar con Python cuando estás empezando a aprender. Y es raro porque, además se ser bastante feo, parece que es algo que no tiene efecto o, al menos, no le encuentras mucho sentido. Te aclaro en este artículo qué es, para qué sirve y qué hace para que puedas quitarte esa sensación de encima.
if __name__ == '__main__' en Python te permite proteger determinado fragmento de código para que no se ejecute en caso de que tu código sea importado, a través de import
, desde otro fichero de Python. De esta manera, ese fragmento solo se ejecutará cuando tu fichero sea invocado directamente.
Bueno, esa ha sido la explicación rápida, vamos a profundizar un poco en ella. Pero antes de seguir, recuerda que te envío un consejo aplicable de Python cada día, solo tienes que suscribirte aquí si te interesa (te puedes dar de baja cuando quieras).
No me gusta contar rollos teóricos. Prefiero explicar las cosas de manera práctica, pero en este caso, hay un par de conceptos que debes conocer. Después de eso, iremos con los ejemplos.
Los módulos en Python
Cuando hacemos alguna prueba o un script pequeñito normalmente usamos la consola de Python.
Si queremos algo más grande, o que necesitemos usar de manera recurrente, lo que hacemos es escribir el código en un fichero de texto (con extensión .py
, normalmente).
Cuando este código crece, por motivos de organización, mantenimiento y legibilidad, entre otros, se suele partir el código y repartirlo en diferentes ficheros.
Pues bien, cada uno de los diferentes ficheros que forman nuestro proyecto, y que contienen nuestro código, es un módulo.
Tan fácil como eso.
Para poder usar las definiciones y el código que se encuentran en otro fichero, hacemos uso del famoso import
.
Por ejemplo, para poder acceder a las definiciones y funciones creadas en el fichero modulo.py
desde otro fichero principal.py
, basta con hacer import modulo
.
Lo vemos. Primero creamos los dos ficheros.
PI = 3.141592
def perimetro(radio):
return 2 * PI * radio
import modulo
print(modulo.PI)
print(modulo.perimetro(10))
Después, si ejecutamos el fichero principal.py
, tendremos el siguiente resultado:
3.141592 62.83184
Sencillo, ¿no? Seguimos.
La variable __name__ y la constante '__main__'
Ahora que ya sabes qué son los módulos, te diré que cuando Python los carga en memoria les asigna un nombre. Ese nombre sirve para identificar al módulo de manera única.
Además, para que tú, como programador, puedas acceder a ese nombre si te hace falta, el intérprete de Python guarda dicho nombre en una variable llamada __name__
.
Te envío todos los días un consejo para que cada día seas mejor en Python.
Siempre sobre Python y programación.
Más de 2500 personas como tú los reciben cada día.
Día que estás fuera, consejo sobre Python que te pierdes.
Antes de suscribirte consulta aquí la
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y comunicaciones comerciales.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.
Sí, el nombre de la variable es un poco raro, con dos símbolos _
antes y después. Es una variable especial.
Python usa muchas de estas variables, también como atributos. Son llamadas variables dunder, nombre que proviene de double underscore (barra baja doble).
Dentro del contexto de cada módulo existe una variable __name__
con el nombre de dicho módulo. Es decir, cada módulo cargado en memoria tiene su propia variable __name__
.
Ahora bien, cuando ejecutamos un fichero de código a través del intérprete, todas la variables __name__
de los módulos que se cargan en memoria tienen como valor el propio nombre del módulo, excepto uno.
El fichero principal, el que ejecutas con python principal.py
(si es que el fichero se llama así), o a través del IDE o editor de código que utilices, no toma su propio nombre como valor para su variable __name__
. El nombre que recibe el módulo principal siempre es __main__
.
De esta manera siempre se puede conocer cuál de los módulos cargados en memoria es el principal.
Ya nos vamos acercando.
Qué pasa al llamar a import
Cuando invocas a un módulo a través de import
sucede una cosa curiosa.
Además de cargarse en memoria, recibir en su variable __name__
su propio nombre y cargar todas las definiciones, todo el código contenido en él se ejecuta.
Es decir, sucede más o menos lo mismo que si ejecutaras ese fichero directamente con python fichero.py
(aunque en ese caso, como ya te he dicho, la variable __name__
toma el valor __main__
).
Lo vemos con el siguiente ejemplo:
print('Esto es un print desde el fichero modulo.py')
import modulo
# No hay más código en este fichero, solo el import
Como puedes ver arriba, en el fichero principal.py
no hay código, solo el import. Si ejecuto dicho fichero, sucederá esto:
Esto es un print desde el fichero modulo.py
Esto sucede porque al importar el módulo modulo.py
desde principal.py
se ejecuta el código contenido en él.
Bueno, creo que a estas alturas ya te estarás oliendo el pastel.
Para qué sirve if __name__ == '__main__'
¿Para qué puedes usar if __name__ == '__main__'
entonces?
Pues teniendo en cuenta que el módulo principal recibe el nombre de __main__
y que se ejecuta el código de los módulos al hacer import
, al usar if __name__ == '__main__'
puedes proteger determinado código para que no se ejecute si el módulo en el que se importa a través de un import
.
Tan simple como eso.
¿Tienes un fragmento de código que solo quieres que se ejecute cuando ese fichero es invocado directamente y no cuando se importa? Pones ese if
.
15 conceptos fundamentales que necesitas conocer para aprender y dominar Python
Te voy a hacer cuatro regalos (no uno, no dos, no tres, cuatro) que hablan de estos 15 conceptos fundamentales de Python: mi Tutorial Básico Interactivo de Python, una cheat sheet de Python en español: La Hoja de Referencia de Python, una guía de ChatGPT y Python y 30 ejercicios de Python (es un reto para ti).
Estos regalos son exclusivos para los suscriptores de Código Pitón.
¿Tienes un fragmento de código que quieres que se ejecute siempre? No pones ese if
.
Los ejemplos
Venga, vamos con los ejemplos para terminar de clarificarlo.
Ejemplo básico
Para entenderlo de todo y que lo veas en funcionamiento, voy a escribir el ejemplo más sencillo y básico.
Dos módulos, uno tiene una función y un código protegido con if __name__ == '__main__'
.
El otro módulo importa al primero para poder usar sus definiciones y tiene su propio código.
Estos son los ficheros:
def funcion():
print('Función de modulo.py')
if __name__ == '__main__':
print('Esto solo se ejecutará si este módulo es invocado directamente.')
print('No se ejecutará si se ejecuta a través de un import.')
import modulo
# Código del fichero principal
print('Esto es el fichero principal, en donde invocamos a la función del módulo.')
modulo.funcion()
Vale, ya tenemos los ficheros. Ahora tenemos dos opciones. Ejecutar el fichero principal o ejecutar el módulo.
Ejecutemos primero el fichero principal con python principal.py
. Este es el resultado:
Esto es el fichero principal, en donde invocamos a la función del módulo. Función de modulo.py
Quiero que te fijes muy bien en lo que ha pasado. Bueno, mejor dicho, quiero que te fijes en lo que no ha pasado.
Solo se ha mostrado el mensaje por pantalla impreso desde principal.py
y desde la función del módulo, pero no los mostrados en el resto del código del módulo, pues están protegidos mediante el if
.
¿Qué sucederá si ejecutamos directamente el módulo? Lo hacemos con python modulo.py
y este es el resultado:
Esto solo se ejecutará si este módulo es invocado directamente. No se ejecutará si se ejecuta a través de un import.
Bueno, creo que ya lo tienes meridianamente claro. Veamos un par de ejemplos complementarios.
Código que solo se ejecuta al hacer import
De la misma forma que puedes hacer que cierto código se ejecute solamente cuando el módulo en el que se encuentra es el principal, puedes hacer lo contrario, es decir, código que se ejecute sólo si es invocado a través de un import
.
Para ello, basta con cambiar el comparador del if de ==
a !=
. O poner un not
delante, pero ya me entiendes.
Otra manera sería añadir una rama else
y colocar en ella el código a ejecutar sólo en caso de no ser el principal.
if __name__ != '__main__': # comparación con !=
print('Esto solo se ejecuta si este módulo no es el principal.')
if __name__ == '__main__':
print('Esto solo se ejecutará si este módulo es invocado directamente.')
print('No se ejecutará si se ejecuta a través de un import.')
else:
print('Esto también se ejecuta solo si este módulo no es el principal.')
import modulo
Veamos qué es lo que pasa al ejecutar principal.py
:
Esto solo se ejecuta si este módulo no es el principal. Esto también se ejecuta solo si este módulo no es el principal.
Si ejecutas directamente el módulo modulo.py
esto es lo que se muestra por pantalla:
Esto solo se ejecutará si este módulo es invocado directamente. No se ejecutará si se ejecuta a través de un import.
Ejemplo completo
Y ya para terminar, veamos un ejemplo completo, con dos ficheros, uno principal y un módulo.
Día que estás fuera, consejo sobre Python que te pierdes.
Antes de suscribirte consulta aquí la
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y comunicaciones comerciales.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.
En ambos habrá código que se ejecute siempre y código protegido con el if
.
Además, se imprimirá en todo momento el valor de la variable __name__
para que quede claro lo que sucede.
Fíjate en que el código de ambos ficheros es muy parecido. Para que la salida por pantalla se interprete de manera más fácil, cualquier mensaje mostrado por el módulo modulo.py
irá antepuesto de una M. En caso de los mensajes mostrados por principal.py
, irán antepuestos de una P
.
print('M: Este código pertenece al módulo modulo.py y SIEMPRE se ejecuta.')
print(f'M: En la ejecución actual, el módulo modulo.py tiene el nombre {__name__=}.')
if __name__ == '__main__':
print('M: Este código pertenece al módulo modulo.py y solo se ejecuta SI ES el módulo principal.')
else:
print('M: Este código pertenece al módulo modulo.py y solo se ejecuta SI NO ES el módulo principal.')
import modulo
print('P: Este código pertenece al módulo principal.py y SIEMPRE se ejecuta.')
print(f'P: En la ejecución actual, el módulo principal.py tiene el nombre {__name__=}.')
if __name__ == '__main__':
print('P: Este código pertenece al módulo principal.py y solo se ejecuta SI ES el módulo principal.')
else:
print('P: Este código pertenece al módulo principal.py y solo se ejecuta SI NO ES el módulo principal.')
Ahora ejecutaremos el fichero principal con python principal.py
:
M: Este código pertenece al módulo modulo.py y SIEMPRE se ejecuta. M: En la ejecución actual, el módulo modulo.py tiene el nombre __name__='modulo'. M: Este código pertenece al módulo modulo.py y solo se ejecuta SI NO ES el módulo principal. P: Este código pertenece al módulo principal.py y SIEMPRE se ejecuta. P: En la ejecución actual, el módulo principal.py tiene el nombre __main__. P: Este código pertenece al módulo principal.py y solo se ejecuta SI ES el módulo principal.
Y ahora, ejecutamos el módulo con python modulo.py
:
M: Este código pertenece al módulo modulo.py y SIEMPRE se ejecuta. M: En la ejecución actual, el módulo modulo.py tiene el nombre __name__='__main__'. M: Este código pertenece al módulo modulo.py y solo se ejecuta SI ES el módulo principal.
Fíjate en los matices y en cuándo se muestra un mensaje y cuándo otro. Fíjate también en el valor que toman las variables __name__
en cada caso.
Espero que ahora sí, ya no te quede ninguna duda.
Si este contenido te ha resultado de utilidad, no dudes en suscribirte a mi lista de correo, pues te llegarán consejos sobre programación y Python todos los días que podrás aplicar para mejorar tus habilidades. Es contenido exclusivo que sólo comparto en esa lista.
Y bueno, también te llegará algún regalito que otro.
Te envío todos los días un consejo para que cada día seas mejor en Python.
Siempre sobre Python y programación.
Más de 2500 personas como tú los reciben cada día.
Día que estás fuera, consejo sobre Python que te pierdes.
Antes de suscribirte consulta aquí la
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y comunicaciones comerciales.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.