if __name__ == “__main__”` — Por qué está en todos los scripts de Python

Abres cualquier proyecto serio de Python y ahí está, al final del fichero, esa línea con cara de jeroglífico:
if __name__ == "__main__":
main()
Si has copiado y pegado esta línea diez veces sin entender qué hace exactamente, esta entrada es para ti. Te la explico de una vez, con un par de ejemplos, y la siguiente vez que la veas (o la escribas) la entenderás de verdad.
Spoiler: tiene que ver con la diferencia entre ejecutar un fichero directamente y importarlo desde otro. Esa es toda la idea. El resto es nomenclatura.
Contenido
La idea en una frase
__name__ es una variable mágica que Python pone automáticamente en cada fichero. Cuando ejecutas el fichero directamente (python miarchivo.py), su valor es "__main__". Cuando lo importas desde otro fichero, su valor es el nombre del módulo ("miarchivo").
Eso significa que el bloque dentro de if __name__ == "__main__": solo se ejecuta cuando el fichero se lanza como script. Si alguien lo importa, ese bloque se salta.
Vamos a verlo en directo
Crea dos ficheros:
# saludos.py
def saludar(nombre):
return f"Hola, {nombre}"
print("Estoy en saludos.py, __name__ es:", __name__)
if __name__ == "__main__":
print(saludar("mundo"))
# main.py
import saludos
print("Estoy en main.py, importando saludos. Su __name__ ahora es:", saludos.__name__)
print(saludos.saludar("Ana"))
Ejecuta ambos:
$ python saludos.py
Estoy en saludos.py, __name__ es: __main__
Hola, mundo
$ python main.py
Estoy en saludos.py, __name__ es: saludos
Estoy en main.py, importando saludos. Su __name__ ahora es: saludos
Hola, Ana
¿Ves la diferencia?
- En el primer caso, ejecutamos
saludos.pydirectamente:__name__vale"__main__". El bloqueifse ejecuta y vemos"Hola, mundo". - En el segundo, importamos
saludosdesdemain.py.__name__dentro desaludos.pyvale"saludos"(el nombre del módulo). El bloque delifno se ejecuta. Pero la funciónsaludar()ya está disponible para quemain.pyla use.
Y eso es toda la magia. Hay un par de matices y casos prácticos, pero la idea ya la tienes entera.
Para qué sirve esto en la vida real
Caso típico: tienes un fichero con funciones útiles, y al final un bloque que las prueba o ejecuta un demo.
# calculadora.py
def sumar(a, b):
return a + b
def restar(a, b):
return a - b
if __name__ == "__main__":
print(sumar(2, 3)) # 5
print(restar(10, 4)) # 6
Si lanzas python calculadora.py, ves el demo. Si en otro fichero haces from calculadora import sumar, no se ejecuta nada del demo — solo se carga la definición de la función.
💡 Es una forma de decir “esto es lo que hace este fichero cuando se ejecuta, no cuando se importa”.
Sin esa línea, el demo se ejecutaría siempre, incluso al importar. Y de pronto al importar calculadora ves prints sueltos en consola que no quieres.
📥 Llévate el cheatsheet de Python (gratis)
PDF de 6 páginas con lo esencial: tipos, condicionales, bucles, estructuras de datos, funciones y los errores que más vas a cometer. Para tener al lado mientras programas.
Sin spam. Te apuntas a la lista, descargas el cheatsheet y recibes contenido de Python cada semana.
Por qué es un patrón estándar
Hay tres motivos por los que verás if __name__ == "__main__": en prácticamente todos los proyectos de Python serios:
1. Permite que el fichero sea a la vez librería y ejecutable. Lo mismo que viste arriba: si hace falta usar las funciones, importas; si quieres ejecutar, lanzas. Un solo fichero, dos usos.
2. Es obligatorio con multiprocessing en Windows. Si lanzas procesos hijos sin proteger el código de arranque con if __name__ == "__main__":, se ejecuta de forma recursiva y el programa se rompe (literalmente). En Linux/Mac es opcional pero recomendado por consistencia.
3. Tests y herramientas lo asumen. Pytest, herramientas de coverage, linters, importadores dinámicos… todo asume que pueden importar un módulo sin que se ejecute código a lo loco. Si tu fichero arranca un servidor o hace un input() al importarse, las herramientas se rompen.
La función main() — convención que ayuda
En la práctica casi todo el mundo escribe esto, no solo el bloque if:
def main():
# toda la lógica de arranque aquí
print(sumar(2, 3))
print(restar(10, 4))
if __name__ == "__main__":
main()
¿Por qué meterlo en una función main() en lugar de poner el código suelto?
- Variables locales. Lo que crees dentro de
main()no contamina el namespace global del módulo. Si pones todo el código suelto, cualquier variable que crees ahí es accesible al importar y puede colisionar. - Más fácil de testear. Puedes llamar a
main()desde un test sin lanzar el script entero. - Más fácil de extender. Si mañana quieres pasar argumentos de línea de comandos, los pillas con
argparsedentro demain().
Es tan común que verás esta plantilla literal en miles de scripts:
import sys
def main():
# tu código aquí
return 0
if __name__ == "__main__":
sys.exit(main())
Los dos guiones bajos — qué demonios son
__name__, __main__, __init__… ¿por qué tantos guiones bajos? Eso es dunder (double underscore). Una convención de Python para decir “esto es mágico/interno del lenguaje, no toques sin saber”.
Otros dunders que ya has visto o verás:
__init__— constructor de una clase.__str__— define cómo se muestra un objeto conprint().__file__— ruta del fichero actual.__doc__— el docstring del módulo o la función.
__name__ es especial: lo gestiona Python automáticamente y siempre vale "__main__" para el script principal y el nombre del módulo para todo lo demás.
⚡ Tip-friki: prueba a poner
print(__name__)al principio de un fichero importado. Te da el nombre completo, comomipaquete.subpaquete.modulo. Es una forma rápida de saber dónde se está ejecutando algo.
Errores típicos al empezar
# 1. Olvidar las dunders (los dos guiones bajos a cada lado)
if __name__ == "main": # ❌ "main", no "__main__"
main()
# 2. Espacios donde no van
if _name_ == "__main__": # ❌ falta el segundo guion bajo en __name__
main()
# 3. Poner código importante FUERA del bloque
saludo = input("Tu nombre: ") # ❌ esto se ejecuta al importar
print(f"Hola, {saludo}")
if __name__ == "__main__": # ✓ esto solo cuando se ejecuta directo
pass
# 4. Asumir que es obligatorio cuando es opcional
# Para scripts sueltos que nunca vas a importar, no lo necesitas:
print("Hola") # un script de 2 líneas no necesita el patrón
Cuándo NO necesitas escribirlo
Si tu fichero es un script de un solo uso, de 5 líneas, que nadie va a importar nunca — no hace falta. Solo es útil cuando:
- El fichero podría importarse desde otro sitio.
- Usas
multiprocessing,concurrent.futures, o lanzas procesos hijos. - Quieres que pytest u otras herramientas puedan importar el módulo sin disparar lógica.
En la duda, ponlo. Es gratis y nunca estorba.
Resumen
| Concepto | Regla |
|---|---|
__name__ | Variable mágica que Python pone en cada fichero |
| Cuando ejecutas el fichero directamente | __name__ vale "__main__" |
| Cuando importas el fichero desde otro | __name__ vale el nombre del módulo |
if __name__ == "__main__": | Bloque que solo se ejecuta al lanzar el fichero como script |
| Convención | Toda la lógica de arranque va dentro de una función main() |
| Cuándo es obligatorio | multiprocessing en Windows; recomendado siempre |
| Cuándo no hace falta | Scripts de un solo uso de pocas líneas que nadie importa |
¿Te ha valido esto?
Si te ha resultado útil, llévate el cheatsheet de Python en PDF — 6 páginas con tipos, condicionales, bucles, estructuras de datos, funciones y los errores típicos. Para tener al lado mientras programas. Gratis.
Sin spam. Email + cheatsheet + un correo por semana con tutoriales nuevos.
Tu siguiente paso
La próxima vez que veas if __name__ == "__main__": ya no es un símbolo mágico copiado de Stack Overflow — sabes exactamente qué hace y por qué. Y cuando empieces a escribir tus propios módulos reutilizables, el patrón sale solo: funciones arriba, main() abajo, if __name__ al final.
Si quieres aprender Python desde cero hasta proyectos reales, con módulos, paquetes, scripts, pytest, deploy… en El Pythonista lo enseño paso a paso.
Un abrazo,
Oscar
¿Quieres aprender Python en orden, no a saltos?
Esto que has leído es solo una pieza. En El Pythonista lo verás todo encadenado: 11 módulos, 37+ horas de vídeo, 734 actividades y un proyecto real (MovieTracker) que crece contigo desde la primera variable hasta el deploy a producción.
37+ horas · 734 actividades · Proyecto real · Acceso de por vida · 14 días de garantía
