Cómo crear un menú interactivo en el terminal con Python

Publicado el: 12/07/2026
Tempo de leitura: 4 minutos
Menu interativo no terminal criado com Python

Un menú interactivo en el terminal permite presentar opciones, recibir una elección y ejecutar funciones sin obligar al usuario a recordar comandos. Es un proyecto ideal para practicar entrada de datos, bucles, condiciones, diccionarios, funciones y manejo de errores. Aunque parece sencillo, un menú bien diseñado debe validar entradas, permitir volver atrás, evitar bucles bloqueados y separar la interfaz de la lógica del programa.

Para reforzar los conceptos utilizados, consulta la guía de input() en Python, el artículo sobre bucles while, el tutorial de funciones, la explicación de diccionarios y la guía de try y except.

Las referencias externas principales son la documentación oficial de input() y el tutorial oficial de control de flujo de Python.

La estructura básica del menú

while True:
    print("\nMENÚ PRINCIPAL")
    print("1. Saludar")
    print("2. Mostrar fecha")
    print("0. Salir")

    opcion = input("Elige una opción: ").strip()

    if opcion == "1":
        print("Hola")
    elif opcion == "2":
        print("Aquí iría la fecha")
    elif opcion == "0":
        print("Hasta luego")
        break
    else:
        print("Opción inválida")

El bucle mantiene activo el programa. break termina cuando el usuario elige salir. Comparar strings evita una conversión innecesaria que podría fallar con letras.

Separar cada acción en una función

from datetime import datetime


def saludar():
    nombre = input("Tu nombre: ").strip()
    if not nombre:
        print("El nombre no puede estar vacío")
        return
    print(f"Hola, {nombre}")


def mostrar_fecha():
    ahora = datetime.now()
    print(ahora.strftime("%d/%m/%Y %H:%M"))

Las funciones reducen el tamaño del bloque principal y facilitan pruebas. Cada acción debe recibir datos y devolver resultados cuando sea posible, en lugar de depender de muchas variables globales.

Crear una función para pausar

def pausar():
    input("\nPulsa Enter para continuar...")

La pausa permite leer el resultado antes de volver al menú. No es necesaria en todos los terminales, pero mejora la experiencia cuando la pantalla se limpia entre acciones.

Limpiar la pantalla de forma multiplataforma

import os


def limpiar_pantalla():
    comando = "cls" if os.name == "nt" else "clear"
    os.system(comando)

os.system() es suficiente para este uso controlado, porque el comando no proviene del usuario. No construyas comandos del sistema concatenando entradas no confiables. También puedes evitar limpiar la pantalla y simplemente imprimir separadores.

Organizar opciones con un diccionario

def salir():
    print("Programa finalizado")
    return False


ACCIONES = {
    "1": saludar,
    "2": mostrar_fecha,
    "0": salir,
}

Después, el menú puede buscar la función:

def ejecutar_menu():
    continuar = True

    while continuar:
        mostrar_menu()
        opcion = input("Elige una opción: ").strip()
        accion = ACCIONES.get(opcion)

        if accion is None:
            print("Opción inválida")
            pausar()
            continue

        resultado = accion()
        if resultado is False:
            continuar = False
        else:
            pausar()

Este enfoque evita una cadena extensa de if y facilita añadir nuevas opciones. Utiliza is None para comprobar que no se encontró una acción.

Mostrar el menú desde una estructura

OPCIONES = {
    "1": ("Saludar", saludar),
    "2": ("Mostrar fecha", mostrar_fecha),
    "0": ("Salir", salir),
}


def mostrar_menu():
    print("\n=== MENÚ PRINCIPAL ===")
    for clave, (texto, _) in OPCIONES.items():
        print(f"{clave}. {texto}")

La misma estructura guarda el texto y la función, evitando mantener dos listas separadas que podrían desincronizarse.

Validar números correctamente

Una acción puede necesitar un entero:

def leer_entero(mensaje, minimo=None, maximo=None):
    while True:
        texto = input(mensaje).strip()
        try:
            valor = int(texto)
        except ValueError:
            print("Escribe un número entero")
            continue

        if minimo is not None and valor < minimo:
            print(f"El valor mínimo es {minimo}")
            continue
        if maximo is not None and valor > maximo:
            print(f"El valor máximo es {maximo}")
            continue

        return valor

Centralizar la validación evita repetir try/except en todas las opciones. Los operadores están escapados en HTML, pero el código ejecutado utiliza los símbolos normales.

Crear un submenú

def menu_configuracion():
    while True:
        print("\nCONFIGURACIÓN")
        print("1. Cambiar idioma")
        print("2. Cambiar tema")
        print("0. Volver")

        opcion = input("Opción: ").strip()

        if opcion == "1":
            print("Idioma actualizado")
        elif opcion == "2":
            print("Tema actualizado")
        elif opcion == "0":
            return
        else:
            print("Opción inválida")

Un return sale del submenú y regresa a la función que lo llamó. Evita usar exit() para navegar entre menús, porque termina todo el proceso.

Guardar datos en JSON

import json
from pathlib import Path

RUTA_CONFIG = Path("config.json")


def guardar_configuracion(config):
    temporal = RUTA_CONFIG.with_suffix(".tmp")
    temporal.write_text(
        json.dumps(config, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )
    temporal.replace(RUTA_CONFIG)

La escritura temporal reduce el riesgo de dejar un archivo incompleto. Valida los datos al cargar y utiliza valores predeterminados cuando el archivo no exista.

Manejar errores sin cerrar el programa

def ejecutar_accion(accion):
    try:
        return accion()
    except FileNotFoundError as error:
        print(f"No se encontró el archivo: {error.filename}")
    except PermissionError:
        print("No tienes permiso para completar la operación")
    except Exception as error:
        print(f"Ocurrió un error inesperado: {error}")

En producción, registra el traceback con logging. Captura excepciones concretas antes de una excepción general. No ocultes errores silenciosamente.

Añadir confirmaciones

def confirmar(mensaje):
    respuesta = input(f"{mensaje} [s/N]: ").strip().casefold()
    return respuesta in {"s", "si", "sí"}

Utiliza confirmaciones antes de borrar archivos, sobrescribir datos o cerrar con cambios pendientes. Una respuesta vacía puede representar la opción segura, en este caso “no”.

Permitir atajos y nombres

alias = {
    "salir": "0",
    "fecha": "2",
    "ayuda": "3",
}

entrada = input("Opción: ").strip().casefold()
opcion = alias.get(entrada, entrada)

Los alias mejoran la usabilidad sin complicar el flujo. Documenta los comandos disponibles y evita nombres ambiguos.

Probar el menú

La función input() dificulta las pruebas cuando está mezclada con toda la lógica. Separa funciones puras:

def resolver_opcion(opcion, acciones):
    return acciones.get(opcion)


def test_resolver_opcion():
    acciones = {"1": saludar}
    assert resolver_opcion("1", acciones) is saludar
    assert resolver_opcion("9", acciones) is None

También puedes usar mocks para simular entradas y capturar salidas. Las acciones que modifican archivos deberían probarse en directorios temporales.

Evitar un menú demasiado grande

Cuando existen decenas de opciones, divide el programa en módulos, crea submenús y considera una interfaz de línea de comandos con argparse. Un menú interactivo funciona bien para herramientas locales y educativas, pero no siempre es la mejor interfaz para automatización.

Ejemplo completo de estructura

def ejecutar():
    while True:
        limpiar_pantalla()
        mostrar_menu()
        opcion = input("Opción: ").strip()

        dato = OPCIONES.get(opcion)
        if dato is None:
            print("Opción inválida")
            pausar()
            continue

        _, accion = dato
        if ejecutar_accion(accion) is False:
            break


if __name__ == "__main__":
    ejecutar()

La protección if __name__ == "__main__" evita iniciar el menú cuando el archivo se importa desde pruebas u otros módulos.

Errores frecuentes

Los problemas más comunes son olvidar la opción de salida, convertir la entrada a entero antes de validarla, repetir toda la lógica dentro de un bloque gigante, usar variables globales, llamar funciones al construir el diccionario y limpiar la pantalla con comandos proporcionados por el usuario. También es frecuente utilizar bucles anidados sin una forma clara de volver.

Conclusión

Un buen menú de terminal combina un bucle controlado, funciones pequeñas, un mapa de opciones y validación reutilizable. Empieza con pocas acciones, separa presentación y lógica y añade manejo de errores. Cuando la herramienta crezca, utiliza módulos, pruebas y submenús. Así obtendrás una interfaz sencilla, mantenible y segura para tus scripts de Python.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    notebook com código saindo da tela
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Variables en Python: guía completa para principiantes

    Aprende variables en Python: asignación, nombres, tipos, conversiones, referencias, mutabilidad, alcance, constantes, None y errores frecuentes.

    Ler mais

    Tempo de leitura: 4 minutos
    12/07/2026
    Diferença entre operadores is e == em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    == vs is en Python: diferencia entre igualdad e identidad

    Entiende la diferencia entre == e is en Python, igualdad, identidad, None, interning, copias superficiales, deepcopy y objetos personalizados.

    Ler mais

    Tempo de leitura: 4 minutos
    12/07/2026
    Uso do operador in em Python para verificação em coleções
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Operador in en Python: pertenencia en listas, strings y sets

    Aprende a usar el operador in y not in con listas, strings, diccionarios, sets, generadores y clases personalizadas mediante __contains__.

    Ler mais

    Tempo de leitura: 4 minutos
    12/07/2026
    Ilustração que representa um algoritmo
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Qué es un algoritmo en programación: guía con Python

    Entiende qué es un algoritmo, cómo describirlo con pseudocódigo, analizar su complejidad y convertirlo en funciones Python comprobables.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Leitura e escrita de arquivos CSV em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Archivos CSV en Python: leer, escribir y procesar datos

    Aprende a leer, escribir, validar y transformar CSV en Python con csv, DictReader, DictWriter, UTF-8, streaming y protección contra errores.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Programador resolvendo problemas com Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Lógica de programación con Python para principiantes

    Aprende lógica de programación con Python mediante algoritmos, pseudocódigo, condiciones, bucles, funciones, validación y pruebas.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026