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!

07 settembre 2022

PythonPillola #11 - match case

Python è un linguaggio in continua evoluzione ed è un aspetto che piace a grandi e piccini, perché permette di esplorare sempre nuovi porti ai marinai digitali (ma che vuol dire? Stupido cervello...). Da Python 3.10 in poi, è stato messo a dispozione un sistema di corrispondenza strutturale, un altro modo di definire un conditional statement, che è conosciuto come match case. Se avete familiarità con altri linguaggi ma anche coi normali costrutti, non avrete assolutamente difficoltà a capirne il funzionamento, e questa pillola è qui per voi per farvi capire senza fatica con un esempio pratico... come sempre del resto.


Questa è una semplice rappresentazione, ed ovviamente non è necessario includere il costrutto dentro una funzione, l'ho fatto solo per semplicità di riutilizzo. Quanto proposto potrebbe essere smarcato anche con un if-elif-else, ma trovo che così sia più semplice ed ordinato, un codice più leggibile. Questione di gusti ovviamente, sentitevi liberi di sperimentare.

18 luglio 2022

PythonPillola #10 - Formattazione stringhe

Più pillole per tutti ed il mondo sarebbe un luogo migliore. Ma non di pillole da ingerire con la bocca, eh no, qui si parla di pillole da consumare con gli occhi. 


 

Oggi parliamo di una delle cose più comode che il nostro linguaggio con le spire ci ha messo a disposizione: la formattazione delle stringhe.

A partire da Python 3.6 è stato inserito un nuovo sistema per la formattazione delle stringhe definito f-string. Facciamo un esempio:


Semplice come bere un bicchiere di pillole,

30 gennaio 2022

PythonPillola #9 - Usare _ nella Python REPL

Era da un po' che non pilloliamo, ed allora oggi ne lancio una semplice semplice.


Nel Python REPL (Read-Evaluate-Print-Loop), che altro  non è che la usatissima console interattiva di Python, possiamo richiamare il risultato dell'ultima operazione effettuata semplicemente con un "_":

 


Davvero molto pillolosa questa pillola.

Alla prossima.

15 marzo 2021

PythonPillola - Lo slicing #8

Nuona PythonPillola e questa volta tocca ad una delle cose più utili del nostro linguaggio, lo slicing. Partiamo subito con la semplice sintassi:
a[start:stop:step]
Quindi per "affettare" qualcosa basterà seguire la sintassi appena presentata e se non verranno specificati i tre parametri, visto che start, stop e step sono opzionali, lo slicing si comporterà di default con:
0 per start
end che corrisponderà alla fine della lista (o quello passato)
1 per lo step
Dai lo sapete ormai, gli esempi sono sempre molto più chiari di qualunque teoria:


Fate un po' di prove e liberate la fantasia, questo argomento merita tutta la vostra attenzione.

13 marzo 2021

PythonPillola - Assegnazione argomenti di una funzione tramite ** e * #7

Nuovo giorno e nuova PythonPillola tra noi. Questa volta lo scopo della #7, è quello di rendere più leggibile e meno furibonda l'assegnazione degli argomenti ad un funzione, specie se siamo davanti ad una moltitudine di elementi. Sia chiaro, quello che vi illustro non è il mio "espediente" preferito (parleremo dei data classes in un'altra PythonPillola), ma diciamo che è il secondo metodo per eleganza e pulizia del codice tra le mie preferenze, anche perché mi rendo conto che non sempre si ha il pieno controllo delle funzioni, magari scritte da un prolisso collega.

Si tratta nello specifico di creare un dizionario per passare i vari argomenti alla funzione tramite l'utilizzo di **, ma che ne dite di un esempio pratico?


Tutto è molto intuitivo, vi faccio solo notare come non importi l'ordine in cui inseriamo la coppia/chiave nel dizionario, questo verrà letto dalla funzione in base alla chiave corrispondente.

Similarmente a quanto proposto, possiamo passare i valori ad una funzione utilizzando una lista o array se preferite, ma questa volta col singolo *:


Ovviamente in questo esempio conterà l'ordine in cui passerete i valori, ma forse non dovevo dirvelo.

Altro giro ed altro regalo, per la #7 è tutto, alla prossima.

Tondo è bello...

Tondo è bello...