Hasta ahora probablemente has escrito código en el REPL —esa sesión interactiva donde Python responde línea a línea. Es útil para explorar, pero tiene un problema fundamental: cuando cierras la sesión, todo desaparece. Un script es simplemente un archivo de texto con instrucciones Python que el intérprete puede ejecutar cuando tú quieras, tantas veces como quieras.
El archivo tiene extensión .py por convención. Y aquí viene algo que sorprende a mucha gente: el intérprete no necesita esa extensión para entender el archivo. Python no mira el nombre del archivo para decidir si es código válido. La extensión es para los humanos —tu editor la usa para activar el resaltado de sintaxis, tu sistema operativo la usa para asociar el archivo con Python, y tú la usas para saber de un vistazo qué hay dentro. Si renombras hola.py a hola.txt y ejecutas python hola.txt, Python lo ejecuta igual. La extensión es un acuerdo social, no un requisito técnico.
Cuando le das un archivo a Python, el intérprete hace algo conceptualmente simple: lo lee de arriba a abajo, en orden, ejecutando cada instrucción al encontrarla. No hay una fase de “análisis previo” que reordene tu código ni ejecute funciones antes de que llegue a ellas. Si en la línea 3 llamas a una función que defines en la línea 10, obtienes un error —porque cuando llega a la línea 3, todavía no ha procesado la línea 10. Esta linealidad es un modelo mental que te va a salvar de muchos bugs.
Hay una distinción importante que vale la pena plantar aquí aunque la veas en detalle más adelante: ejecutar un script y importar un módulo son dos maneras diferentes de que Python procese el mismo archivo. Cuando ejecutas python mi_script.py, Python asigna el nombre especial __main__ al módulo que está corriendo. Cuando importas ese mismo archivo desde otro lugar, recibe su nombre real. Esa diferencia de identidad cambia el comportamiento del programa, y es la base del patrón if __name__ == "__main__" que verás en todas partes.
# saludo.py
# Un script completo y ejecutable que demuestra la lectura lineal
# y el punto de entrada estándar de Python.
def construir_saludo(nombre, veces):
# Construimos el mensaje en memoria antes de imprimirlo
lineas = []
for i in range(veces):
lineas.append(f"Hola, {nombre}! (repetición {i + 1})")
return "\n".join(lineas)
def main():
nombre = "Mundo"
repeticiones = 3
mensaje = construir_saludo(nombre, repeticiones)
print(mensaje)
# Esto imprime "__main__" cuando ejecutas el archivo directamente.
# Imprimiría "saludo" si otro archivo hiciera: import saludo
print(f"\nEste archivo se llama: {__name__}")
# Python llega aquí después de haber definido todo lo de arriba.
# Solo ejecuta main() si este archivo es el punto de entrada,
# no si alguien lo importa como módulo.
if __name__ == "__main__":
main()
Para ejecutarlo, abre una terminal, navega al directorio donde guardaste el archivo y escribe:
python saludo.py
Qué está pasando realmente
Cuando Python abre saludo.py, empieza en la línea 1 y baja. Las líneas def construir_saludo(...) y def main() no ejecutan las funciones —las definen y las guardan en memoria con ese nombre. Es como escribir una receta en un libro: leer la receta no es cocinar.
Cuando Python llega al bloque if __name__ == "__main__":, evalúa la condición. Como el archivo se está ejecutando directamente, __name__ vale "__main__", la condición es verdadera, y se llama a main(). Solo en ese momento Python entra en la función.
La función main() no es mágica en Python —no es como el main() obligatorio de C. Es simplemente una función con ese nombre que nosotros elegimos llamar. La convención existe porque organiza el código: todo lo que “arranca” el programa vive en un lugar conocido, y el resto del archivo son definiciones reutilizables.
La variable __name__ es la que revela la diferencia entre ejecutar e importar. Si desde otro script haces import saludo, Python procesa el archivo igualmente de arriba a abajo, pero __name__ vale "saludo". La condición del if es falsa, main() nunca se llama, y solo quedan las funciones disponibles para quien importó. El mismo archivo, dos comportamientos distintos según el contexto —eso es lo que hace que un archivo .py pueda ser a la vez un script y una biblioteca.
Errores que debes conocer
Error: llamar a una función antes de definirla, olvidando que Python lee el archivo en orden.
# ❌ Wrong
resultado = duplicar(5) # Python aún no sabe qué es "duplicar"
def duplicar(n):
return n * 2
# ✅ Right
def duplicar(n):
return n * 2
resultado = duplicar(5) # Ahora sí existe en memoria
La definición debe aparecer antes de la llamada porque el intérprete ejecuta línea a línea; cuando llega a duplicar(5), busca ese nombre en memoria y no lo encuentra.
Error: guardar el archivo como .txt o sin extensión y luego confundirse con por qué el editor no colorea el código.
# ❌ Wrong → mi_programa.txt # El intérprete lo ejecuta igual, pero tu editor no activa # el soporte de Python: sin autocompletado, sin resaltado, # sin detección de errores mientras escribes. # ✅ Right → mi_programa.py # La extensión activa todas las herramientas del ecosistema.
El intérprete es indiferente, pero todo lo demás —editores, linters, herramientas de empaquetado— espera la extensión .py.
N° 12