W3docs

Variabili Globali in Python

Scopri come funzionano le variabili globali in Python, come modificarle con la parola chiave global, evitare gli errori UnboundLocalError e quando usare alternative.

Le variabili globali in Python sono variabili dichiarate al di fuori di qualsiasi funzione. Esistono per tutta la durata del programma e possono essere lette da qualunque punto — ma per modificarle all'interno di una funzione è necessaria la parola chiave global. Questa pagina spiega come funzionano le variabili globali, le insidie da evitare e quando è meglio ricorrere ad alternative più appropriate.

Cosa Sono le Variabili Globali?

Una variabile globale viene creata nello scope del modulo (livello superiore) — al di fuori di qualsiasi funzione o classe. Qualsiasi codice nello stesso modulo può leggerla senza alcuna dichiarazione speciale.

python— editable, runs on the server

Python utilizza la regola LEGB per risolvere i nomi: esegue la ricerca negli scope Local → Enclosing → Global → Built-in in quest'ordine. Una variabile globale si trova al livello "G", quindi ogni funzione riesce a trovarla dopo aver esaurito i propri scope locali e circostanti. Consulta Python Scope per una spiegazione completa di tutti e quattro i livelli.

Lettura vs. Modifica delle Variabili Globali

Leggere una variabile globale (funziona sempre)

Per impostazione predefinita, una funzione può leggere qualsiasi variabile globale senza alcuna sintassi speciale:

language = "Python"

def print_language():
    print(language)  # reads the global

print_language()  # Output: Python

La parola chiave global — necessaria per la modifica

Se si tenta di assegnare a una variabile all'interno di una funzione, Python crea una nuova variabile locale invece di aggiornare quella globale. Per modificare la variabile globale, è necessario dichiararla con la parola chiave global:

counter = 0

def increment():
    global counter   # tell Python we mean the global 'counter'
    counter += 1
    print("Counter:", counter)

increment()  # Output: Counter: 1
increment()  # Output: Counter: 2
print(counter)  # Output: 2

Senza global counter, la riga counter += 1 genererebbe un UnboundLocalError perché Python cercherebbe di leggere una variabile locale chiamata counter prima che venisse assegnata.

L'Insidia dell'UnboundLocalError

Questo è l'errore più comune con le variabili globali. Nel momento in cui Python vede qualsiasi assegnazione a un nome all'interno di una funzione, tratta quel nome come locale per tutta la funzione — anche nelle righe precedenti all'assegnazione:

x = 10

def broken():
    print(x)   # ERROR — Python sees the assignment below and marks x as local
    x = 20

broken()
# UnboundLocalError: local variable 'x' referenced before assignment

Per correggere il problema, aggiungere global x all'inizio della funzione se si ha davvero bisogno di modificare la variabile globale, oppure rinominare la variabile locale se si vuole una copia indipendente.

Shadowing delle Variabili

Assegnare a un nome all'interno di una funzione senza la parola chiave global crea una variabile locale che nasconde (shadowing) quella globale — la variabile globale non viene modificata:

count = 100

def show_count():
    count = 5   # local variable — shadows the global 'count'
    print("Inside function:", count)   # 5

show_count()
print("Outside function:", count)  # 100 — global is unchanged

Lo shadowing non è un errore, ma può creare confusione. Usare nomi distinti per rendere evidente l'intento.

global nelle Funzioni Annidate

Se si ha bisogno di accedere a una variabile globale di livello modulo da una funzione interna (annidata), si deve usare global — non nonlocal. nonlocal raggiunge solo lo scope della funzione immediatamente circostante, non il livello del modulo:

total = 0

def outer():
    def inner():
        global total   # reaches module scope
        total += 10
    inner()

outer()
outer()
print("total:", total)  # Output: total: 20

Confronta questo con nonlocal, che modifica la variabile della funzione circostante ma lascia invariata la variabile globale a livello di modulo:

x = "global"

def outer():
    x = "outer"
    def inner():
        nonlocal x   # modifies outer()'s x, not the module-level x
        x = "inner"
    inner()
    print("outer x after inner():", x)  # inner

outer()
print("global x after outer():", x)   # global — unchanged

Per un approfondimento su nonlocal, consulta Python Scope.

Costanti a Livello di Modulo — Il Caso d'Uso Appropriato

L'utilizzo più legittimo delle variabili globali a livello di modulo riguarda le costanti — valori impostati una sola volta e mai modificati durante l'esecuzione. Per convenzione, si scrivono in UPPER_SNAKE_CASE:

MAX_RETRIES = 3
DEFAULT_TIMEOUT = 30

def connect(host, retries=MAX_RETRIES, timeout=DEFAULT_TIMEOUT):
    print(f"Connecting to {host} with {retries} retries, timeout={timeout}s")

connect("db.example.com")
# Output: Connecting to db.example.com with 3 retries, timeout=30s

Le costanti non richiedono mai la parola chiave global perché vengono solo lette, mai riassegnate.

Buone Pratiche

1. Preferire argomenti di funzione e valori di ritorno

Passare i dati tramite le firme delle funzioni rende il codice più facile da testare e da comprendere. Questa funzione pura è più semplice rispetto all'uso di un counter globale mutabile:

def increment(counter):
    return counter + 1

counter = 0
counter = increment(counter)
counter = increment(counter)
print("counter:", counter)  # Output: counter: 2

2. Riservare i globali alle vere costanti a livello di modulo

Usare le variabili globali per valori genuinamente fissi per tutta la durata del programma (MAX_CONNECTIONS, APP_VERSION, configurazione caricata una sola volta all'avvio). Evitare variabili globali mutabili che cambiano nel tempo.

3. Usare nomi descrittivi in UPPER_SNAKE_CASE per le costanti

Un nome come MAX_RETRIES è immediatamente riconoscibile come costante di modulo. Un nome come r non lo è.

4. Inizializzare prima dell'uso

Dichiarare tutte le variabili globali all'inizio del modulo, prima di qualsiasi funzione che le utilizzi. Questo previene NameError nel caso in cui una funzione venga chiamata prima che la variabile sia stata definita.

5. Prestare attenzione con i thread

Se più thread chiamano funzioni che modificano la stessa variabile globale, si genera una race condition. Proteggere lo stato mutabile condiviso con un threading.Lock, oppure riprogettare il codice per evitare lo stato condiviso. Consulta Python Variables per una panoramica più ampia dei tipi di variabile in Python.

SituazioneCosa fare
Leggere una variabile globale dentro una funzioneNon è necessario nulla di speciale
Modificare una variabile globale dentro una funzioneAggiungere global <name> all'inizio della funzione
Modificare la variabile di una funzione circostanteUsare nonlocal <name>
Condividere un valore fisso tra molte funzioniDichiarare una costante a livello di modulo in UPPER_SNAKE_CASE
Condividere stato mutabile tra funzioniPreferire argomenti di funzione e valori di ritorno

Esercitazione

Pratica
In Python, what are the properties of Global Variables?
In Python, what are the properties of Global Variables?
Was this page helpful?