python-corrutinas

Qué son y cómo usar corrutinas en Python

Las corrutinas en Python son una forma de realizar tareas asincrónicas y concurrentes.

Una corrutina en Python es una función que puede pausarse y luego reanudarse, permitiendo que otras tareas se ejecuten en el ínterin.

Esta capacidad de suspensión y reanudación las hace adecuadas para tareas que implican concurrencia (como la programación asincrónica, la manipulación de flujos de datos y la creación de pipelines de procesamiento).

En cierta forma, la corrutinas son similares a los generadores, pero con capacidades adicionales. Mientras que los generadores producen una secuencia de valores, las corrutinas pueden consumir valores, producir valores y gestionar el flujo de control.

Definición de una corrutina

Las corrutinas se definen utilizando la palabra clave async def en lugar de def, y utilizan await para suspender la ejecución y esperar a que otra tarea se complete.

# Ejemplo básico de una corrutina
import asyncio

async def mi_corrutina():
    print("Comenzando la corrutina")
    await asyncio.sleep(1)
    print("Corrutina finalizada")

En este ejemplo, mi_corrutina es una función asincrónica que utiliza await para pausar su ejecución durante 1 segundo (simulando una tarea asíncrona como una espera de E/S o una solicitud de red).

Ejecución de corrutinas

El módulo asyncio de Python proporciona un marco para escribir código asincrónico utilizando corrutinas y realizar operaciones I/O eficientes.

Para ejecutar una corrutina, debemos añadirla al bucle de eventos de asyncio. La manera más sencilla de hacerlo es con asyncio.run().

import asyncio

async def saludar():
    print("Hola mundo")
    await asyncio.sleep(1)
    print("Desde LuisLlamas")

asyncio.run(saludar())

# salida:
# hola mundo
# ...(espera de un segundo)...
# Desde LuisLlamas

En este ejemplo, saludar es una corrutina que se ejecuta en el bucle de eventos de asyncio. La ejecución se pausa durante 1 segundo entre los dos print.

Esperar a múltiples corrutinas

Las corrutinas son especialmente útiles cuando se necesitan realizar múltiples operaciones asincrónicas. Esto se puede gestionar utilizando asyncio.gather().

import asyncio

async def tarea(numero):
    print(f"Comenzando tarea {numero}")
    await asyncio.sleep(1)
    print(f"Terminando tarea {numero}")

async def main():
    await asyncio.gather(tarea(1), tarea(2), tarea(3))

asyncio.run(main())

En este ejemplo, main espera a que se completen tres corrutinas tarea en paralelo.

Ejemplos prácticos