La línea más rara de Python — desmitificada
Abre casi cualquier archivo Python y eventualmente verás esto al final:
if __name__ == "__main__":
main()
Parece un poco de boilerplate mágico. En realidad es una feature muy práctica una vez que sabes lo que hace — y existe porque Python no traza una línea entre "scripts" y "librerías".
El montaje: dos formas de usar un archivo
Cada archivo .py en Python se puede usar de dos formas distintas:
- Como script — lo ejecutas directamente con
python3 file.py. - Como módulo — otro archivo lo importa con
import file.
El lenguaje no te obliga a declarar cuál de los dos estás escribiendo. Cualquier archivo podría terminar haciendo las dos cosas.
Considera un archivo llamado math_helpers.py:
# math_helpers.py
def mean(values):
return sum(values) / len(values)
def median(values):
s = sorted(values)
mid = len(s) // 2
if len(s) % 2 == 0:
return (s[mid - 1] + s[mid]) / 2
return s[mid]
# Test rápido mientras desarrollo
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print("mean:", mean(numbers))
print("median:", median(numbers))
Si ejecutas este archivo directamente, imprime la salida del test — bien. Pero si otro archivo hace import math_helpers, esas sentencias print se ejecutan durante el import. Cada usuario del módulo ve tu salida de pruebas de desarrollo. No tan bien.
Qué es __name__
Cada módulo Python tiene una variable incorporada llamada __name__. Python la establece automáticamente:
- Cuando el archivo se importa,
__name__se pone al nombre de import del módulo —"math_helpers"en el ejemplo de arriba. - Cuando el archivo se ejecuta directamente, Python pone
__name__al string especial"__main__".
Eso te da una forma de saber en qué modo estás. Envuelve el código "solo script" en una comprobación:
# math_helpers.py
def mean(values):
return sum(values) / len(values)
def median(values):
s = sorted(values)
mid = len(s) // 2
if len(s) % 2 == 0:
return (s[mid - 1] + s[mid]) / 2
return s[mid]
if __name__ == "__main__":
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print("mean:", mean(numbers))
print("median:", median(numbers))
Ahora python3 math_helpers.py imprime la salida del test. Pero import math_helpers desde otro archivo se salta el bloque entero — las funciones están disponibles y no se ejecuta nada no deseado.
El compañero común: una función main()
La mayoría de scripts reales hacen crecer una función main() dedicada y mantienen el bloque del guardia diminuto:
# process_orders.py
import sys
def load_orders(path):
with open(path) as f:
return [line.strip() for line in f if line.strip()]
def process(orders):
for order in orders:
print(f"Processing {order}")
def main():
if len(sys.argv) < 2:
print("Usage: python3 process_orders.py <file>")
sys.exit(1)
orders = load_orders(sys.argv[1])
process(orders)
if __name__ == "__main__":
main()
¿Por qué molestarse con una main() en vez de poner la lógica directamente bajo el guardia if?
- Testeabilidad. Puedes importar el módulo y llamar a
main()(o a cualquiera de los helpers) desde los tests. - Variables locales. Cualquier cosa definida dentro de
main()es una variable local, no un nombre a nivel de módulo. Eso evita colisiones accidentales de nombres y hace la superficie pública del módulo más limpia. - Legibilidad. El bloque del guardia ahora son dos líneas — un "punto de entrada del script" claro en vez de un montón de lógica.
Una demostración rápida
Puedes ver el comportamiento directamente:
Cuando ejecutas el fragmento de arriba con Python, imprime __name__ is: __main__ y "being run as a script". Si otro archivo importara este, la misma comprobación imprimiría la otra rama.
Cuándo no necesitas el guardia
Muchos archivos Python nunca crecen uno. Los scripts cortos que nadie importaría están bien sin él:
# one_off_rename.py
import os
for name in os.listdir("."):
if name.endswith(".txt"):
os.rename(name, name.lower())
Eso está perfectamente bien. No estás construyendo una librería; nadie va a importar esto. En el momento en que haya lógica reutilizable en un archivo, sin embargo — y quieras mantener el código con efectos secundarios junto a ella — recurre al guardia.
Puntos de entrada para paquetes instalados
Cuando estés publicando tu código como un paquete de verdad, hay un mecanismo más formal: entry_points en los metadatos de tu paquete, que mapean un comando a una función. Los usuarios que instalen tu paquete obtienen un comando de shell que llama directamente a la función. Pero para scripts que se ejecutan desde una carpeta en tu propia máquina, el guardia __main__ es la herramienta estándar.
Cerrando este capítulo
Ahora tienes:
- Funciones para dar nombre a tu lógica.
*args/**kwargspara llamadas flexibles.- Lambdas para funciones desechables.
- Decoradores y type hints para envolver y documentar esas funciones.
- Módulos, pip y entornos virtuales para partir código entre archivos y proyectos.
- El guardia
__main__para dejar coexistir scripts y módulos.
Siguiente: clases
En su mayor parte has estado emparejando funciones con datos simples — dicts, listas, tuplas. El siguiente capítulo introduce las clases, la forma que tiene Python de atar datos y comportamiento juntos, y el sitio donde viven conceptos como self, __init__, la herencia y los dataclasses.
Preguntas frecuentes
¿Qué hace if __name__ == '__main__'?
if __name__ == '__main__'?Solo ejecuta el bloque de debajo cuando el archivo se ejecuta directamente (no cuando el archivo se importa como módulo). Esto te deja escribir un archivo .py que puede ejecutarse como script o ser importado por sus funciones y clases — sin que las acciones del script pasen durante el import.
¿Python necesita una función main?
No. Los archivos Python se ejecutan de arriba a abajo automáticamente. Pero en cuanto un archivo tiene lógica que también quieres que sea importable, el guardia if __name__ == '__main__' se vuelve importante — y poner el trabajo de nivel superior del script dentro de una función main() es un hábito compañero común.
¿Cuál es la diferencia entre __name__ y __main__?
__name__ y __main__?__name__ es una variable especial que Python establece en cada módulo. Si el archivo se importa, __name__ es el nombre del módulo (como 'util'). Si el archivo se ejecuta directamente, Python pone __name__ al string '__main__'. La comprobación if compara los dos.