Variabili Locali v. Globali

Nella lezione precedente abbiamo visto che per gestire la programmazione ad eventi dovremo definire delle funzioni di handler. Queste funzioni avranno bisogno di condividere delle informazioni comuni per poter cooperare. In questa lezione vedremo una tecnica che ci permetterà di ottenere questo risultato: l'utilizzo di un insieme di variabili globali.

Ogni volta che una variabile viene definita al di fuori di una funzione, questa è una variabile globale. Quindi, anche senza sapere cosa fossero, le abbiamo già usate nelle settimane precedenti.

Le variabili che sono definite all'interno delle funzioni sono invece variabili locali. Vediamo un esempio:

    # num1 e' una variabile globale
    num1 = 1
    print num1

    # num2 e' una variabile locale
    def fun():
        num1 = 2
        num2 = num1 + 1
        print num2
    

In questo caso la variabile num1 è una variabile globale, perché definita al di fuori della funzione. Può essere comunque utilizzata all'interno della funzione per effettuare delle operazioni. La variabile num2, invece, viene dichiarata per la prima volta all'interno della funzione ed è quindi una variabile locale.

Viste così, sembra non ci sia poi una grande differenza fra num1 e num2, ma se proviamo a stampare il valore di entrambe al di fuori della funzione:

    # la variabile num1 rimane definita per tutto il programma
    print num1

    # la variabile num2 esiste solo all'interno di fun(), 
    #     qui ci troviamo al di fuori e risulta non definita
    print num2
    

la variabile num1 verrà stampata senza problemi, mentre la num2 restituirà un errore NameError di variabile non definita. Questa variabile esiste solo fintanto che la funzione viene eseguita, appena ritorna al processo principale, la variabile non esiste più.

Il valore di num2 stampato dalla funzione è 3, mentre la variabile num1, stampata al di fuori della funzione vale 1. Come è possibile questa cosa, da che all'interno della funzione viene definita num2 = num1 + 1?

All'interno della funzione non vi è alcun riferimento al fatto che la variabile num1 utilizzata sia quella globale. Viene inizializzata, tramite l'istruzione num1 = 2 come nuova variabile locale esistente solo all'interno della funzione. L'istruzione num2 = num1 + 1 restituisce quindi 3, mentre al di fuori della funzione esisterà solo la variabile num1 globale che non è mai stata modificata. Se avessimo scritto la funzione come:

    def fun():
        num2 = num1 + 1
        print num2
    

a questo punto la variabile num1, non riinizializzata all'interno della funzione, sarà proprio la variabile globale e stavolta num2 = 2. Oltre ad utilizzare una variabile globale come argomento nei calcoli, è possibile modificarne il valore all'interno della funzione introducendola con la parola chiave global. Ad esempio:

    def fun():
        global num1
        num1 = 2
        num2 = num1 + 1
        print num2
    

farebbe sì che num2 = 3, come nel primo esempio, ma, al termine della funzione, la variabile globale num1 varrà 2.

Per evitare confusioni è decisamente sconsigliato di riutilizzare delle variabili globali come variabili locali all'interno di funzioni.

Ora, quali sono i vantaggi di usare variabili locali all'interno delle funzioni?

  • per assegnare un nome rappresentativo ad una quantità
  • per immagazzinare un'informazione ed evitare di ricalcolarla ogni volta che ci serve

Un esempio può essere dato dalla seguente funzione di conversione di gradi Fahrenheit in Kelvin in cui variabili locali vengono utilizzate per entrambi i motivi precedenti.

    def fahren_to_kelvin(fahren):
        celsius = 5.0 / 9 * (fahren - 32)
        zero_celsius_in_kelvin = 273.15
        return celsius + zero_celsius_in_kelvin

E' sempre meglio usare delle variabili locali al posto di variabili globali, a meno di non avere delle specifiche ragioni per farlo. Infatti le variabili globali possono essere molto pericolose e causare, in seguito a delle piccole sviste, delle interferenze fra funzioni molto diverse fra loro difficili da individuare e correggere.

Facciamo un esempio abbastanza stupido a riguardo. Supponiamo che all'interno del software che gestisce un aereo il sistema di controllo di volo e quello di instrattenimento dei passeggeri utilizzino entrambi una variabile dial. Se questa variabile fosse definita come globale, potremmo avere che un passeggero che modifica il volume causi anche una modifica nella posizione dei flap, con conseguenze davvero terribili.


Con il pulsante sottostante è possibile accedere al codice completo utilizzato durante questa lezione, in modo da poter effettuare voi stessi prove ed esperimenti.