ProgrammazioneSviluppatore Backend

Che cos'è l'ambito (scope) delle variabili in Python e come funziona la parola chiave `global`? Porta un esempio pratico in cui una comprensione errata dell'ambito porta a errori.

Supera i colloqui con l'assistente IA Hintsage

Risposta.

L'ambito (scope) di una variabile è il contesto in cui è accessibile. In Python ci sono 4 ambiti principali, che puoi ricordare con il principio LEGB:

  • Local (locale) — all'interno di una funzione.
  • Enclosing (incapsulante) — all'interno di funzioni esterne per funzioni annidate.
  • Global (globale) — a livello di modulo.
  • Built-in (nomi incorporati di Python).

La parola chiave global consente di modificare una variabile dichiarata a livello globale dall'interno di una funzione.

def foo(): global my_var my_var = 10 # modifica la variabile globale

Senza global, all'interno della funzione la variabile è considerata locale, anche se esiste un nome simile nell'ambito esterno.

Domanda ingannevole.

"Cosa stamperà il seguente codice?"

x = 10 def func(): x = 20 func() print(x)

Risposta: Stamperà 10, perché all'interno della funzione viene creata una nuova variabile locale x, la globale non viene modificata.

Esempi di errori reali a causa della mancata comprensione delle sottigliezze dell'argomento.


Storia

Nel gestore comandi di un bot volevano mantenere un contatore globale, ma hanno dimenticato il global:

counter = 0 def increment(): counter += 1 # UnboundLocalError: variabile locale 'counter' referenziata prima dell'assegnazione

Errore causato dal fatto che l'interprete considera counter una variabile locale (poiché all'interno della funzione c'è un'assegnazione), e non globale.


Storia

Nelle funzioni annidate hanno dimenticato che senza la parola chiave nonlocal una variabile nascosta crea un ambito locale:

def outer(): x = 0 def inner(): x += 1 # UnboundLocalError, x è considerato locale in inner

Corretto:

def outer(): x = 0 def inner(): nonlocal x x += 1

Storia

Hanno scritto una riga:

x = 5 y = (lambda: (x := x + 1))() # SyntaxError in Python < 3.8, o UnboundLocalError più tardi

Hanno dimenticato la differenza di ambito tra un'espressione e una lambda. Non tutte le costruzioni supportano l'assegnazione all'interno di una lambda, a seconda della versione di Python.