Bucles en Python
La automatización existe porque los humanos somos ineficientes repitiendo tareas. Si necesitas reiniciar un servicio en un servidor, escribes un comando. Si necesitas hacerlo en 500 servidores, escribes un bucle.
En Python, disponemos de dos estructuras de control iterativas principales: for y while. Entender cuándo usar cada una es clave para diseñar scripts de infraestructura eficientes.
Bucle for (Iteración Definida)
Utilizamos el bucle for cuando conocemos de antemano la colección de elementos que queremos recorrer (por ejemplo, una lista de IPs, una lista de puertos o las claves de un diccionario). El bucle procesará cada elemento secuencialmente.
# Iterar sobre una lista de nodos de un clúster
nodos_db = ["db-master-01", "db-replica-01", "db-replica-02"]
for nodo in nodos_db:
print(f"Ejecutando backup en: {nodo}...")
En ocasiones, necesitamos iterar un número específico de veces sin una colección predefinida (por ejemplo, reintentar una conexión 3 veces). Para esto usamos la función generadora range().
# Configurar 3 reintentos para una conexión de red
max_retries = 3
for intento in range(max_retries):
print(f"Intento de conexión {intento + 1}/{max_retries}")
# Lógica de conexión aquí...
Bucle while (Iteración Indefinida)
A diferencia del for, el bucle while no itera sobre una colección, sino que se repite mientras una condición booleana se evalúe como True. Es la estructura ideal para rutinas de “polling” (consultar constantemente el estado de un servicio hasta que responda).
# Simulación de un polling para esperar a que un servicio levante
servicio_listo = False
intentos = 0
while not servicio_listo and intentos < 5:
print("El servicio aún no responde. Esperando 5 segundos...")
intentos += 1
# Aquí iría la lógica real de comprobación
if intentos == 3:
servicio_listo = True # Simulamos que levanta al 3er intento
print("Servicio en línea. Continuando despliegue.")
Control de Flujo: break y continue
A veces necesitamos alterar el comportamiento natural de un bucle basándonos en eventos que ocurren durante la iteración.
La sentencia break aborta el bucle por completo. Es crucial para optimizar búsquedas: si ya encontraste el nodo que falló, no tiene sentido seguir iterando sobre los 400 restantes.
servidores = ["web-1 (OK)", "web-2 (FAIL)", "web-3 (OK)", "web-4 (OK)"]
for server in servidores:
print(f"Analizando {server}")
if "FAIL" in server:
print(">>> Fallo crítico detectado. Abortando análisis.")
break # El bucle termina inmediatamente aquí
Por otro lado, continue detiene la iteración actual y salta inmediatamente a la siguiente. Es excelente para ignorar elementos que no requieren procesamiento.
puertos = [80, 443, 22, 8080]
for puerto in puertos:
if puerto == 22:
print(f"Ignorando puerto {puerto} (Administrativo)")
continue # Salta el resto del bloque y evalúa el siguiente puerto
print(f"Configurando reglas de firewall para el puerto de aplicación {puerto}")
Dominar estas estructuras te permite escalar tus herramientas. Un bloque lógico dentro de un bucle bien diseñado funciona igual de bien para un servidor que para mil.