1
Gestire gli errori e richiedere aiuto
Per favore, non antropomorfizzate i computer, perchĂ© lo trovo molto noioso. Quando i computer vi mostrano un messaggio di errore, non Ăš perchĂ© li avete offesi. I computer sono forse gli strumenti piĂč sofisticati con cui la maggior parte di noi interagirĂ , tuttavia restano comunque degli strumenti.
Nonostante ciĂČ, Ăš facile dare la colpa ai computer. Dato che buona parte dellâapprendimento della programmazione Ăš auto-referenziale, Ăš normale avvertire il fallimento quando dovete continuamente consultare Internet svariate volte al giorno, anche se state studiando Python da mesi. Tuttavia anche gli sviluppatori professionisti consultano Internet o la documentazione per rispondere alle loro domande di programmazione.
A meno che non abbiate le risorse finanziarie o sociali per assumere un tutor privato che possa rispondere alle vostre domande, sarete limitati al vostro computer, ai motori di ricerca su Internet e alla vostra forza dâanimo. Fortunatamente le vostre domande sono quasi certamente giĂ state poste in precedenza. Come programmatori, essere in grado di trovare le risposte per conto vostro Ăš molto piĂč importante che conoscere qualunque algoritmo o struttura di dati. Questo capitolo vi guiderĂ attraverso la conoscenza di questa skill fondamentale.
Come capire i messaggi di errore di Python
Quando si trovano di fronte a un vero e proprio muro di messaggi testuali tecnologici, il primo impulso di molti programmatori Ăš di ignorarli completamente. Tuttavia in questi messaggi di errore si trova la risposta su ciĂČ che non funziona nel vostro programma. Trovare questa risposta Ăš un procedimento diviso in due passi: esaminare il traceback ed eseguire una ricerca su Internet con il messaggio di errore.
Esaminare i traceback
I programmi in Python vanno in crash quando il codice solleva unâeccezione che la dichiarazione except non riesce a gestire. Quando ciĂČ accade, Python visualizza il messaggio dellâeccezione e un traceback. Chiamato anche stack trace, il traceback mostra il punto allâinterno del programma in cui Ăš avvenuta lâeccezione e il percorso di chiamate alle funzioni che lâha attivata.
Per fare pratica nella lettura dei traceback, scrivete il seguente programma, che contiene dei bug, e salvatelo come abcTraceback.py. I numeri di riga sono solo un riferimento e non fanno parte del programma.
In questo programma la funzione a() chiama b() â¶, che a sua volta chiama c() â·. Allâinterno di c(), lâespressione 42 / 0 âž provoca un errore di divisione per zero. Quando eseguite questo programma, lâoutput dovrebbe assomigliare al seguente:
Esaminiamo questo traceback riga per riga, iniziando da questo punto:
Questo messaggio vi fa sapere che quello che segue Ăš un traceback. Il testo most recent call last indica che ciascuna delle chiamate alle funzioni Ăš elencata in ordine, a partire dalla prima chiamata per terminare con quella piĂč recente.
La riga successiva mostra la prima chiamata a una funzione del traceback:
Queste due righe rappresentano il frame summary e mostrano le informazioni allâinterno di un oggetto frame. Quando una funzione viene invocata, i dati della variabile locale, insieme al punto allâinterno del codice in cui deve restituire informazioni, sono memorizzati in un oggetto frame. Gli oggetti frame contengono le variabili locali e altri dati associati alle chiamate alle funzioni. Gli oggetti frame vengono creati quando la funzione viene chiamata e distrutti quando la funzione esegue il return. Il traceback mostra un frame summary per ciascun frame che porta al crash. Possiamo vedere che la chiamata alla funzione Ăš sulla riga 13 di abcTraceback.py, mentre il testo <module> ci informa che questa riga Ăš nel global scope. La riga 13 viene mostrata con due spazi di indentazione.
Le quattro righe che seguono rappresentano i due prossimi frame summary:
Grazie al testo line 3, in a possiamo capire che b() Ăš stata chiamata nella riga 3 allâinterno della funzione a(), cosa che ha fatto sĂŹ che c() venisse chiamata nella riga 7 allâinterno della funzione b(). Notate che le chiamate print() alle righe 2, 6 e 10 non vengono mostrate nel traceback, anche se sono state eseguite prima che avvenissero le chiamate alle funzioni. Nel traceback vengono visualizzate solo le righe che contengono le chiamate a funzioni che hanno portato allâeccezione.
Lâultimo frame summary mostra la riga che ha provocato lâeccezione di tipo unhandled, seguita dal nome dellâeccezione e dal relativo messaggio:
Notate che il numero di riga prodotto dal traceback Ăš il punto in cui Python ha rilevato un errore. La vera fonte del bug potrebbe trovarsi da qualche parte prima di questa riga.
I messaggi di errore sono notoriamente brevi e imperscrutabili: le tre parole division by zero non vi comunicano nulla in particolare, a meno che non sappiate che la divisione per zero Ăš matematicamente impossibile e che si tratta di un bug frequente dei software. In questo programma il bug non Ăš difficile da scovare. Osservando la riga di codice nel frame summary, Ăš piuttosto chiaro che nel testo 42 / 0 si sta verificando una divisione per zero.
Diamo perĂČ unâocchiata a un caso piĂč complesso. Scrivete questo codice in un editor di testo e salvatelo come zeroDivideTraceback.py:
Quando eseguite questo programma, lâoutput dovrebbe essere simile a questo:
Il messaggio di errore Ăš il medesimo, ma...