10.1 Variabili locali della funzione
In Python una variabile è disponibile (può essere utilizzata) dal momento della sua creazione fino alla fine del suo ambito di visibilità — nella maggior parte dei casi è la funzione in cui è dichiarata. Se una variabile è dichiarata fuori da tutte le funzioni, allora è chiamata globale.
In Python gli ambiti di visibilità delle variabili determinano il contesto in cui le variabili sono disponibili per l'uso. Gli ambiti di visibilità aiutano ad evitare conflitti di nomi e a gestire l'accesso ai dati. I principali tipi di ambito in Python includono:
Ambito locale: Le variabili create all'interno di una funzione esistono nell'ambito locale di quella funzione e sono accessibili solo all'interno di essa.
Ambito delle funzioni annidate: Se una funzione è definita all'interno di un'altra funzione, le sue variabili sono accessibili solo all'interno di questa funzione annidata.
Ambito globale: Le variabili definite a livello di script o modulo sono considerate globali e accessibili da qualsiasi parte del codice nello stesso modulo.
Ambito incorporato: È un ambito speciale che include tutti gli
oggetti e le funzioni Python predefiniti, disponibili di default (ad esempio,
print()
e len()
).
Regola LEGB
Per risolvere le variabili Python utilizza la regola LEGB, che definisce l'ordine in cui l'interprete cerca le variabili:
- L (Local) — Prima ricerca nell'ambito locale.
- E (Enclosed) — Poi negli ambiti di tutte le funzioni annidate, dalla più vicina a quella esterna.
- G (Global) — Poi nell'ambito globale.
- B (Built-in) — Infine nell'ambito incorporato.
Esempi di utilizzo
x = "global" # Variabile globale
def outer():
y = "outer local" # Variabile locale della funzione esterna
def inner():
z = "inner local" # Variabile locale della funzione annidata
print(x) # Mostra "global"
print(y) # Mostra "outer local"
print(z) # Mostra "inner local"
inner()
outer()
La variabile z
è disponibile solo all'interno della funzione inner()
.
La variabile y
è disponibile all'interno della funzione outer()
e in tutte le funzioni dichiarate al suo interno.
La variabile x
è disponibile ovunque nel file corrente (modulo).
10.2 Accesso alle variabili globali: global x
Una caratteristica interessante del linguaggio Python è che le variabili dagli ambiti esterni (in cui è annidato l'ambito corrente) possono essere solo lette.
Tentando di assegnare qualcosa a una variabile esterna, verrà creata una variabile locale con lo stesso nome e l'accesso alla variabile esterna sarà perso.
Esempio:
x = 10
def change_global():
print(x) # Questo provocherà un errore, poiché x sarà considerata una variabile locale dopo l'assegnazione
x = 20 # Qui verrà creata una variabile locale x
print(x) # Mostrerà 20 (si riferisce alla variabile locale x)
change_global()
print(x) # Mostrerà 10
Questo esempio non funziona e solleverà un errore UnboundLocalError
, perché l'interprete Python inizialmente vede l'assegnazione x = 20
e considera x
una variabile locale. Tuttavia, quando l'interprete arriva alla riga print(x)
, non trova la variabile locale x
, poiché non è ancora stata definita.
Ciò è fatto per sicurezza, affinché le variabili locali non modifichino accidentalmente quelle globali.
Operatore global
Se è necessario modificare consapevolmente il valore di una variabile globale all'interno di una funzione, è possibile utilizzare l'operatore global
. Questo operatore permette di indicare esplicitamente che la modifica deve avvenire sulla variabile globale, non su quella locale.
Per modificare il valore di una variabile globale all'interno di una funzione, è necessario dichiarare questa variabile all'inizio della funzione usando global
. Ciò dà alla funzione accesso in scrittura alla variabile:
x = 10
def change_global():
global x # Dichiarare x come variabile globale
print(x) # Mostra 10 (si riferisce alla variabile globale x)
x = 20 # Qui si assegna un nuovo valore alla variabile globale x
print(x) # Mostra 20 (si riferisce alla variabile globale x)
change_global()
print(x) # Mostra 20
L'utilizzo dell'operatore global
permette di evitare errori e gestire correttamente le variabili globali.
Le variabili globali possono rendere il programma meno prevedibile e più difficile da comprendere, poiché i loro valori possono essere cambiati in qualsiasi punto del programma. Questo è particolarmente critico se il programma è grande e sviluppato da un gruppo di programmatori.
Anche se a volte l'uso di variabili globali è inevitabile, è meglio cercare di minimizzarne l'uso. Invece delle variabili globali, considera l'uso di parametri di funzione, valori restituiti e classi per memorizzare lo stato.
L'uso di variabili globali può portare a effetti collaterali inaspettati, rendere difficile il debug e il testing del codice, e ridurne la riusabilità. Pertanto, si consiglia di utilizzare le variabili globali con cautela e solo quando è davvero necessario.
10.3 Accesso alle variabili non locali: nonlocal
Oltre alle variabili globali e locali, in Python esistono variabili da ambiti intermedi. Ad esempio, quando una funzione è annidata in un'altra funzione. Per lavorare con tali variabili si usa l'operatore nonlocal
.
L'operatore nonlocal
permette di lavorare con le variabili nelle funzioni annidate, modificando i loro valori nell'ambito più vicino, escludendo le variabili globali.
L'operatore nonlocal
aiuta a evitare la creazione di una nuova variabile locale nella funzione annidata quando è necessario modificare una variabile definita nella funzione esterna. Senza l'uso di nonlocal
, le modifiche riguardano solo la variabile locale della funzione interna, senza influire sulla variabile della funzione esterna.
Esempio:
def outer():
count = 0
def inner():
nonlocal count
count += 1
return count
return inner
counter = outer()
print(counter()) # Mostrerà 1
Ecco un esempio più pratico dell'uso di nonlocal
per creare un contatore:
def create_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter = create_counter()
print(counter()) # Mostrerà 1
print(counter()) # Mostrerà 2
print(counter()) # Mostrerà 3
Questo esempio dimostra come nonlocal
possa essere utilizzato in scenari reali per creare una funzione che mantiene il suo stato tra le chiamate.
GO TO FULL VERSION