La programación asíncrona permite que un programa realice múltiples tareas al mismo tiempo sin bloquear la ejecución. En Python, el módulo asyncio proporciona una infraestructura poderosa para escribir código concurrente usando la sintaxis async y await.

Conceptos Clave

  1. Corutinas: Funciones que pueden ser pausadas y reanudadas, permitiendo la ejecución de otras tareas mientras esperan.
  2. Eventos: Mecanismo que permite a las corutinas esperar hasta que ocurra una condición específica.
  3. Loop de Eventos: El núcleo de asyncio, que ejecuta las corutinas y maneja los eventos.

Sintaxis Básica

Definición de Corutinas

Las corutinas se definen usando la palabra clave async:

import asyncio

async def say_hello():
    print("Hello")
    await asyncio.sleep(1)
    print("World")

Ejecutar Corutinas

Para ejecutar una corutina, se usa asyncio.run():

asyncio.run(say_hello())

Ejemplo Práctico

Vamos a crear un ejemplo donde varias corutinas se ejecutan concurrentemente:

import asyncio

async def task(name, delay):
    print(f"Task {name} started")
    await asyncio.sleep(delay)
    print(f"Task {name} finished after {delay} seconds")

async def main():
    await asyncio.gather(
        task("A", 2),
        task("B", 1),
        task("C", 3)
    )

asyncio.run(main())

Explicación del Código

  1. Definición de Corutinas:

    async def task(name, delay):
        print(f"Task {name} started")
        await asyncio.sleep(delay)
        print(f"Task {name} finished after {delay} seconds")
    
    • task es una corutina que simula una tarea que toma delay segundos para completarse.
    • await asyncio.sleep(delay) pausa la corutina por delay segundos sin bloquear el loop de eventos.
  2. Ejecutar Múltiples Corutinas Concurrentemente:

    async def main():
        await asyncio.gather(
            task("A", 2),
            task("B", 1),
            task("C", 3)
        )
    
    • asyncio.gather ejecuta múltiples corutinas concurrentemente y espera a que todas terminen.
  3. Iniciar el Loop de Eventos:

    asyncio.run(main())
    
    • asyncio.run(main()) inicia el loop de eventos y ejecuta la corutina main.

Ejercicios Prácticos

Ejercicio 1: Descargar Páginas Web Concurrentemente

Escribe un programa que descargue el contenido de varias páginas web concurrentemente usando asyncio y aiohttp.

import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    urls = [
        'https://www.python.org',
        'https://www.asyncio.org',
        'https://www.github.com'
    ]
    tasks = [fetch(url) for url in urls]
    results = await asyncio.gather(*tasks)
    for result in results:
        print(result[:100])  # Imprimir los primeros 100 caracteres de cada página

asyncio.run(main())

Solución del Ejercicio 1

  1. Importar Módulos Necesarios:

    import asyncio
    import aiohttp
    
  2. Definir la Corutina fetch:

    async def fetch(url):
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                return await response.text()
    
    • aiohttp.ClientSession se usa para manejar la sesión HTTP.
    • session.get(url) realiza una solicitud GET a la URL.
    • await response.text() obtiene el contenido de la respuesta.
  3. Definir la Corutina main:

    async def main():
        urls = [
            'https://www.python.org',
            'https://www.asyncio.org',
            'https://www.github.com'
        ]
        tasks = [fetch(url) for url in urls]
        results = await asyncio.gather(*tasks)
        for result in results:
            print(result[:100])  # Imprimir los primeros 100 caracteres de cada página
    
    • urls es una lista de URLs para descargar.
    • tasks es una lista de corutinas fetch para cada URL.
    • await asyncio.gather(*tasks) ejecuta todas las corutinas concurrentemente y espera a que todas terminen.
    • for result in results imprime los primeros 100 caracteres de cada página descargada.
  4. Iniciar el Loop de Eventos:

    asyncio.run(main())
    

Resumen

En esta sección, hemos aprendido sobre la programación asíncrona en Python usando el módulo asyncio. Hemos cubierto los conceptos básicos de corutinas, eventos y el loop de eventos, y hemos visto cómo ejecutar corutinas concurrentemente. También hemos trabajado con un ejemplo práctico de descarga de páginas web concurrentemente.

En el próximo módulo, exploraremos técnicas avanzadas de concurrencia, incluyendo el uso de hilos y procesos.

Curso de Programación en Python

Módulo 1: Introducción a Python

Módulo 2: Estructuras de Control

Módulo 3: Funciones y Módulos

Módulo 4: Estructuras de Datos

Módulo 5: Programación Orientada a Objetos

Módulo 6: Manejo de Archivos

Módulo 7: Manejo de Errores y Excepciones

Módulo 8: Temas Avanzados

Módulo 9: Pruebas y Depuración

Módulo 10: Desarrollo Web con Python

Módulo 11: Ciencia de Datos con Python

Módulo 12: Proyecto Final

© Copyright 2024. Todos los derechos reservados