Introducció
La programació asíncrona permet que un programa gestioni múltiples operacions al mateix temps sense bloquejar l'execució. En Python, asyncio
és una biblioteca que proporciona una infraestructura per escriure codi concurrent utilitzant la sintaxi async
i await
.
Conceptes Clau
- Coroutines: Funcions especials que poden ser pausades i reprèses durant la seva execució.
- Event Loop: Un bucle que gestiona i executa les coroutines.
- Tasks: Coroutines que s'executen en l'event loop.
- Futures: Objectes que representen el resultat d'una operació asíncrona.
Configuració de l'Entorn
Abans de començar, assegura't de tenir instal·lada la versió de Python 3.7 o superior, ja que asyncio
està integrat a partir d'aquestes versions.
Sintaxi Bàsica
Definició de Coroutines
Les coroutines es defineixen utilitzant la paraula clau async
abans de la definició de la funció.
Executar Coroutines
Per executar una coroutine, utilitzem asyncio.run()
.
Crear i Executar Tasks
Les tasks permeten executar múltiples coroutines concurrentment.
async def di_hola(): print("Hola") await asyncio.sleep(1) print("Adéu") async def main(): task1 = asyncio.create_task(di_hola()) task2 = asyncio.create_task(di_hola()) await task1 await task2 asyncio.run(main())
Exemples Pràctics
Exemple 1: Descàrrega de Dades Simultània
import asyncio async def descarrega_dades(url): print(f"Començant la descàrrega de {url}") await asyncio.sleep(2) # Simula la descàrrega print(f"Descàrrega completada de {url}") async def main(): urls = ["http://exemple.com/1", "http://exemple.com/2", "http://exemple.com/3"] tasks = [asyncio.create_task(descarrega_dades(url)) for url in urls] await asyncio.gather(*tasks) asyncio.run(main())
Exemple 2: Tasques amb Resultats
import asyncio async def calcula_quadrat(x): await asyncio.sleep(1) return x * x async def main(): results = await asyncio.gather( calcula_quadrat(1), calcula_quadrat(2), calcula_quadrat(3) ) print(results) asyncio.run(main())
Exercicis Pràctics
Exercici 1: Simulació de Tasques
Crea una funció asíncrona que simuli la realització de diverses tasques (per exemple, tasques de processament de dades) i imprimeixi un missatge quan cada tasca es completi.
Solució
import asyncio async def processa_tasca(nom, temps): print(f"Començant la tasca {nom}") await asyncio.sleep(temps) print(f"Tasca {nom} completada") async def main(): tasques = [ asyncio.create_task(processa_tasca("A", 2)), asyncio.create_task(processa_tasca("B", 3)), asyncio.create_task(processa_tasca("C", 1)) ] await asyncio.gather(*tasques) asyncio.run(main())
Exercici 2: Descàrrega de Fitxers
Simula la descàrrega de diversos fitxers de diferents mides i imprimeix un missatge quan cada descàrrega es completi.
Solució
import asyncio async def descarrega_fitxer(nom, mida): print(f"Començant la descàrrega del fitxer {nom} de mida {mida}MB") await asyncio.sleep(mida) # Simula el temps de descàrrega basat en la mida print(f"Descàrrega del fitxer {nom} completada") async def main(): fitxers = [ ("fitxer1", 2), ("fitxer2", 5), ("fitxer3", 3) ] tasques = [asyncio.create_task(descarrega_fitxer(nom, mida)) for nom, mida in fitxers] await asyncio.gather(*tasques) asyncio.run(main())
Errors Comuns i Consells
- No oblidar
await
: Quan crides una coroutine, assegura't d'utilitzarawait
per esperar el seu resultat. - No barrejar
asyncio.run()
amb altres event loops:asyncio.run()
s'ha d'utilitzar una sola vegada en el programa principal. - Gestionar excepcions: Utilitza blocs
try
iexcept
dins de les coroutines per gestionar errors asíncrons.
Conclusió
En aquesta secció, hem après els conceptes bàsics de la programació asíncrona amb asyncio
en Python. Hem vist com definir i executar coroutines, crear i gestionar tasks, i hem practicat amb exemples i exercicis pràctics. La programació asíncrona és una eina poderosa per millorar l'eficiència dels nostres programes, especialment quan es tracta de tasques I/O intensives.
Curs de Programació en Python
Mòdul 1: Introducció a Python
- Introducció a Python
- Configuració de l'Entorn de Desenvolupament
- Sintaxi de Python i Tipus de Dades Bàsics
- Variables i Constants
- Entrada i Sortida Bàsiques
Mòdul 2: Estructures de Control
Mòdul 3: Funcions i Mòduls
- Definició de Funcions
- Arguments de Funció
- Funcions Lambda
- Mòduls i Paquets
- Visió General de la Biblioteca Estàndard
Mòdul 4: Estructures de Dades
Mòdul 5: Programació Orientada a Objectes
Mòdul 6: Gestió de Fitxers
- Lectura i Escriptura de Fitxers
- Treballant amb Fitxers CSV
- Gestió de Dades JSON
- Operacions amb Fitxers i Directoris
Mòdul 7: Gestió d'Errors i Excepcions
Mòdul 8: Temes Avançats
- Decoradors
- Generadors
- Gestors de Context
- Concurrència: Fils i Processos
- Asyncio per a Programació Asíncrona
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries amb unittest
- Desenvolupament Guiat per Proves
- Tècniques de Depuració
- Ús de pdb per a la Depuració
Mòdul 10: Desenvolupament Web amb Python
- Introducció al Desenvolupament Web
- Conceptes Bàsics del Framework Flask
- Construcció d'APIs REST amb Flask
- Introducció a Django
- Construcció d'Aplicacions Web amb Django
Mòdul 11: Ciència de Dades amb Python
- Introducció a la Ciència de Dades
- NumPy per al Càlcul Numèric
- Pandas per a la Manipulació de Dades
- Matplotlib per a la Visualització de Dades
- Introducció al Machine Learning amb scikit-learn