19 luglio 2024

Pillola di Python #13 - Programmazione asincrona con asyncio



Python offre un potente modulo chiamato asyncio per la programmazione asincrona, che permette di scrivere codice non bloccante utilizzando le parole chiave async e await. Questo approccio è ideale per gestire operazioni I/O-bound come richieste di rete, lettura/scrittura su file, e altre attività che possono beneficiare della concorrenza senza il sovraccarico dei thread o dei processi.

Introduzione a asyncio

asyncio è stato introdotto in Python 3.4 e permette di eseguire funzioni asincrone in un ciclo di eventi (event loop). Le funzioni asincrone sono definite con la parola chiave async, e le chiamate a funzioni asincrone utilizzano la parola chiave await.

Esempio Base di asyncio

Vediamo un esempio di base per capire come funziona asyncio:



Si otterrà:
Ciao, Dee!
Ciao, Kiki!
Ciao, Bolla!
Arrivederci, Dee!
Arrivederci, Kiki!
Arrivederci, Bolla!
Cosa abbiamo fatto con quel codice? Vediamolo insieme:
- Siamo partiti dalla Definizione di Funzioni Asincrone, saluta(nome) è una funzione asincrona che stampa un messaggio di saluto, aspetta un secondo (simulando un'attività I/O), e poi stampa un messaggio di congedo.
- main() è la funzione principale asincrona che utilizza asyncio.gather per eseguire più funzioni saluta in parallelo.
- Si eseguono gli eventi ed asyncio.run(main()) esegue la funzione main all'interno del ciclo di eventi, gestendo automaticamente l'avvio e la chiusura.

Ovviamente questo è un esempio basilare, l'argomento è vastissimo, ma la programmazione asincrona con asyncio permette di scrivere codice non bloccante che può gestire operazioni I/O in modo efficiente. Utilizzando async e await, è possibile eseguire funzioni asincrone in parallelo, migliorando le prestazioni delle applicazioni che richiedono molte operazioni I/O. Sperimenta con asyncio per vedere come può migliorare il tuo prossimo progetto Python!

01 luglio 2024

Pillola di Python #12 - La Potenza dei Decoratori



I decoratori in Python sono una funzionalità potente e flessibile che permette di modificare il comportamento di una funzione o di una classe. Questa funzionalità è particolarmente utile per implementare aspetti trasversali come la registrazione dei log, la gestione delle transazioni e la convalida degli input.

Che Cosa Sono i Decoratori?
In sintesi, un decoratore è una funzione che prende un'altra funzione e ritorna una nuova funzione con un comportamento esteso o modificato. Ecco un esempio base:


L'output sarà... rullo di tamburi:
Qualcosa sta accadendo prima della funzione.
Eseguendo la funzione principale.
Qualcosa sta accadendo dopo la funzione.
I decoratori possono anche accettare argomenti. Questo permette di creare decoratori altamente configurabili:


Ed otterrete:
Ciao, Dee!
Ciao, Dee!
Ciao, Dee!

I decoratori sono un potente strumento che può essere utilizzato per migliorare la leggibilità e la manutenibilità del codice. Possono essere utilizzati per implementare funzionalità trasversali in modo pulito ed efficiente, riducendo la duplicazione del codice e migliorando la separazione delle preoccupazioni.

Sperimentate con i decoratori nel vostro prossimo progetto Python per vedere come possono semplificare e migliorare il vostro codice!

14 giugno 2024

Python fa piovere

Beh di cosa vi stupite, Python può farlo. 

Il codice non è mio, ma non ricordo esattamente la fonte, ma insomma provatelo e ditemi se non è divertentissimo.




from collections import deque
import random
import shutil
from time import sleep


TERMINAL_WIDTH, TERMINAL_HEIGHT = shutil.get_terminal_size()
RAIN_DENSITY = 0.15
EMPTY_LINE = " " * TERMINAL_WIDTH

lines = deque([EMPTY_LINE for _ in range(TERMINAL_HEIGHT)], maxlen=TERMINAL_HEIGHT)

def build_next_line(source):
    next_row = ["|" if char == "v" else " " for char in source]
    for idx, _ in enumerate(next_row):
        if random.random() < RAIN_DENSITY:
             next_row[idx] = "v"
    return "".join(next_row)

while True:
    new_row = build_next_line(lines[0])
    lines.appendleft(new_row)
    for row in lines:
        print(row)
    sleep(0.05)

08 maggio 2024

Python 3.13: Il Grande Fiasco della Scomparsa del GIL

Cari pythonisti e non, benvenuti alla più grande rivoluzione dai tempi della scoperta che il latte non si versa prima del tè! Python 3.13 sta arrivando, e no, non è una nuova versione del famoso gruppo comico, ma quasi. Preparatevi a ridere, piangere e gridare "Ni!" alla notizia più succosa dell'anno: la potenziale rimozione del Global Interpreter Lock, meglio noto come il GIL.

Che diavolo è il GIL? 

Il GIL, ovvero il Grande Impedimento Lineare (ok, non proprio, ma ci siamo capiti), è stato per anni il cattivo di ogni sviluppatore Python. Introdotto per semplificare la gestione della memoria, il GIL ha fatto il suo lavoro, ma ha anche reso impossibile per Python eseguire più processi contemporaneamente. Immaginate di avere una squadra di supermegagilirobot pronti a lavorare, ma con una sola chiave inglese da passarsi. Ecco, questo è il GIL. 

Perché mandare il GIL in pensione? 

La comunità Python ha da tempo cercato di sbarazzarsi di questo fastidioso elemento, un po' come cercare di sbarazzarsi di un cactus in un palloncino. La rimozione del GIL promette di aprire nuovi orizzonti di "parallelismo" alle massime prestazioni, rendendo Python il linguaggio preferito non solo per chi vuole scrivere codice, ma anche per chi vuole fare festa con i core della CPU. E che festa...

I mantaggi di un Python senza GIL  

  • Prestazioni Più Veloci di una Rondine Africana: Senza il GIL, Python potrà finalmente sfruttare tutti i core della CPU, come una rondine che trasporta... noci di cocco. Questo significa che le applicazioni multi-threaded potranno volare come mai prima d'ora. 
  • Scalabilità per il Regno di Camelot: Immaginate server web Python che gestiscono migliaia di connessioni simultanee senza sudare una goccia. La rimozione del GIL potrebbe trasformare Python in un cavaliere della tavola rotonda del mondo web, pronto a scalare castelli di traffico web con facilità. 
  • Ecosistema Espanso Come la Leggenda di Re Artù: Con un Python senza GIL, il linguaggio potrebbe vedere un'esplosione di nuovi utenti e librerie. Sarà come un'epopea cavalleresca in cui Python diventa l'eroe indiscusso dei linguaggi di programmazione. 

Le Sfide della Rimozione del GIL  

Ma non tutto è rosa e fiori (o campi di battaglia medievali). Rimuovere il GIL porta con sé una serie di sfide degne dei più astuti trabocchetti del castello di Aaaaargh. Senza il GIL, la sicurezza dei thread deve essere garantita, e gli sviluppatori potrebbero trovarsi a lottare contro draghi di complessità e bug selvatici. 

Le librerie esistenti, che hanno fatto affidamento sul GIL come un cavaliere sulla sua armatura, dovranno essere aggiornate. Questo richiederà tempo, sforzi e, probabilmente, un po' di magia oscura. 

Python 3.13: L'Alba di un Nuovo Giorno 

La comunità Python, armata di entusiasmo e buone intenzioni, sta lavorando instancabilmente per portare questa rivoluzione a termine. Con la rimozione del GIL, Python 3.13 promette di essere un evento epocale, paragonabile solo alla scoperta del Graal del parallelismo. 

Quindi, preparatevi, cavalieri del codice, perché Python 3.13 sta arrivando. Sarà un'avventura epica, piena di insidie e trionfi, ma alla fine, la comunità Python sarà più forte e il linguaggio più potente. Che il vostro codice sia senza bug e che il vostro GIL sia per sempre sconfitto. E ricordate, nessun sistema di thread sicuro si ottiene senza un po' di confusione e, naturalmente, senza un senso dell'umorismo degno dei Monty Python. 

Avanti, verso il rilascio di Python 3.13! Ni!

Tondo è bello...

Tondo è bello...