Python - Closures: Una guida per principianti
Ciao, aspirante programmatore Python! Oggi, intraprenderemo un viaggio avventuroso nel mondo delle closure. Non preoccuparti se non hai mai sentito questo termine prima – alla fine di questo tutorial, non solo capirai cosa siano le closure, ma sarai anche in grado di crearle e usarle nel tuo codice. Allora, immergiamoci!
Cos'è una Closure?
Immagina di avere una scatola magica che può ricordare cose anche dopo averla chiusa. Questo è essenzialmente cosa è una closure nel programmazione! In Python, una closure è un oggetto funzione che ricorda i valori nello scope circostante anche se non sono presenti in memoria.
Sembra confuso? Spezziamo tutto giù:
- È una funzione all'interno di un'altra funzione.
- Può accedere alle variabili dalla funzione esterna.
- Ricorda queste variabili anche quando la funzione esterna ha terminato l'esecuzione.
Pensa a questo come un modo per creare un piccolo pacchetto di funzionalità che porta i suoi dati privati con sé. Cool, no?
Funzioni nidificate
Prima di immergerci più a fondo nelle closure, parliamo delle funzioni nidificate. Queste sono semplicemente funzioni definite all'interno di altre funzioni. Ecco un esempio semplice:
def funzione_esterna(x):
def funzione_interna(y):
return x + y
return funzione_interna
risultato = funzione_esterna(10)
print(risultato(5)) # Output: 15
In questo esempio, funzione_interna
è nidificata all'interno di funzione_esterna
. La funzione interna può accedere al parametro x
della funzione esterna. Questo è un concetto chiave per comprendere le closure.
Ambito delle variabili
Per capire davvero le closure, dobbiamo comprendere l'ambito delle variabili in Python. Ci sono tre tipi di ambito:
- Ambito locale: Variabili definite all'interno di una funzione
- Ambito circostante: Variabili nella funzione esterna delle funzioni nidificate
- Ambito globale: Variabili definite al livello superiore di un modulo
Ecco un esempio per illustrare:
x = "Sono globale!" # Ambito globale
def esterna():
y = "Sono dall'esterna!" # Ambito circostante
def interna():
z = "Sono locale!" # Ambito locale
print(x, y, z)
interna()
esterna()
Quando esegui questo codice, vedrai tutte e tre le variabili stampate. La funzione interna
può accedere alle variabili da tutti e tre gli ambiti!
Creare una Closure
Ora che comprendiamo le funzioni nidificate e l'ambito delle variabili, creiamo una closure. Una closure si verifica quando una funzione nidificata fa riferimento a un valore nel suo ambito circostante. Ecco un esempio:
def moltiplica_per(n):
def moltiplicatore(x):
return x * n
return moltiplicatore
volte_due = moltiplica_per(2)
volte_tre = moltiplica_per(3)
print(volte_due(5)) # Output: 10
print(volte_tre(5)) # Output: 15
In questo esempio, moltiplica_per
è la nostra funzione esterna, e moltiplicatore
è la nostra funzione interna. La magia avviene quando restituiamo moltiplicatore
- ricorda il valore di n
anche dopo che moltiplica_per
ha terminato l'esecuzione. Questa è una closure!
Spezziamo tutto giù passo per passo:
- Definiamo
moltiplica_per
che prende un parametron
. - All'interno di
moltiplica_per
, definiamomoltiplicatore
che prende un parametrox
. -
moltiplicatore
utilizza siax
(il suo parametro proprio) chen
(dalla funzione esterna). - Restituiamo
moltiplicatore
damoltiplica_per
. - Quando chiamiamo
moltiplica_per(2)
, restituisce una funzione che moltiplica sempre il suo input per 2. - Allo stesso modo,
moltiplica_per(3)
restituisce una funzione che moltiplica sempre il suo input per 3.
Questo è il potere delle closure - possono creare funzioni specializzate al volo!
La parola chiave nonlocal
A volte, potresti voler modificare una variabile dall'ambito circostante all'interno della tua funzione interna. Python fornisce la parola chiave nonlocal
per questo scopo. Ecco un esempio:
def contatore():
conto = 0
def incremento():
nonlocal conto
conto += 1
return conto
return incremento
mio_contatore = contatore()
print(mio_contatore()) # Output: 1
print(mio_contatore()) # Output: 2
print(mio_contatore()) # Output: 3
In questo esempio, incremento
è una closure che ricorda e modifica la variabile conto
dal suo ambito circostante. La parola chiave nonlocal
dice a Python che conto
non è una variabile locale, ma una dall'ambito circostante.
Uso pratico delle Closure
Le closure non sono solo un trucco cool - hanno applicazioni pratiche! Ecco alcune:
- Nascondimento dei dati e incapsulamento
- Creazione di fabbriche di funzioni
- Implementazione di decoratori
Guardiamo un esempio del mondo reale. Immagina di creare un sistema di sconti per un negozio online:
def crea_ajustatore_di_prezzo(sconto):
def ajusta_prezzo(prezzo):
return prezzo * (1 - sconto)
return ajusta_prezzo
sconto_black_friday = crea_ajustatore_di_prezzo(0.2) # 20% di sconto
sconto_cyber_monday = crea_ajustatore_di_prezzo(0.15) # 15% di sconto
prezzo_originale = 100
print(f"Prezzo Black Friday: ${sconto_black_friday(prezzo_originale)}")
print(f"Prezzo Cyber Monday: ${sconto_cyber_monday(prezzo_originale)}")
Questo codice crea diverse funzioni di定价 per diversi eventi di sconto, tutte utilizzando la stessa funzione di base. Questo è il potere delle closure!
Sintesi
Congratulations! Hai appena imparato una delle caratteristiche più avanzate di Python. Ricapitoliamo ciò che abbiamo coperto:
Concetto | Descrizione |
---|---|
Closure | Una funzione che ricorda i valori nello scope circostante |
Funzione nidificata | Una funzione definita all'interno di un'altra funzione |
Ambito delle variabili | La visibilità delle variabili (locale, circostante, globale) |
nonlocal |
Parola chiave per modificare le variabili nell'ambito circostante |
Ricorda, come ogni strumento potente, le closure dovrebbero essere utilizzate con giudizio. Sono grandi per certi compiti, ma usarle troppo può rendere il tuo codice più difficile da capire. Pratica, sperimenta, e presto sarai in grado di utilizzare le closure come un professionista Python!
Buon coding, e ricorda - in Python, come nella vita, è quello che c'è dentro (funzione) che conta!
Credits: Image by storyset