5 errori Python comuni e come correggerli

Introduzione
Python è apprezzato per la sua sintassi chiara e leggibile, ma anche in questo linguaggio gli errori sono inevitabili quando si impara o si sviluppa codice complesso. Conoscere i messaggi di errore più comuni e sapere come interpretarli accelera il debug e riduce i tempi di sviluppo. Questo articolo si concentra su cinque eccezioni e errori che riceverai più spesso: IndentationError, SyntaxError, IndexError, ValueError e AttributeError. Per ciascuno trovi spiegazioni, esempi eseguibili, come prevenirli, e come testarli.
Important: leggere i messaggi dell’interprete. Spesso l’errore indica linea e posizione approssimativa.
Cosa intendo per «errore» e «eccezione»
- Errore (error): condizione che impedisce al programma di essere eseguito correttamente.
- Eccezione (exception): evento sollevato durante l’esecuzione che può essere intercettato con try/except.
Ora analizziamo gli errori dal 5 al 1 come nell’ordine di frequenza di segnalazione.
5 IndentationError
Definizione breve: l’IndentationError è sollevato quando il livello di indentazione non rispetta la struttura a blocchi richiesta da Python.
Perché succede: Python usa l’indentazione per determinare i blocchi (condizioni, cicli, funzioni). Se le righe all’interno di un blocco non hanno la stessa indentazione o se si mescolano tab e spazi, l’interprete segnala IndentationError.
Esempio errato:
for i in range(5):
print(i)

Spiegazione: la riga print(i) non è indentata rispetto al for, perciò Python non trova il corpo del ciclo.
Correzione:
for i in range(5):
print(i)Cause comuni e casi subdoli
- Copia e incolla tra editor che usano impostazioni di tab/space diverse.
- Miscelare tab e spazi nella stessa base di codice. L’errore può non essere visibile a occhio nudo.
- Rientri diversi in funzioni o blocchi lunghi.
Prevenzione
- Configura l’editor per usare 4 spazi invece dei tab (o viceversa, ma scegli uno standard).
- Abilita la visualizzazione di caratteri invisibili (tab e spazi) nel tuo editor.
- Usa un formatter automatico (black, autopep8) per uniformare il codice.
Checklist rapida per IndentationError
- L’editor è impostato su spazi (o tab) in modo coerente?
- Esegui un formatter prima del commit?
- Tutti i blocchi hanno la stessa indentazione?
Quando l’approccio fallisce
- Se ricevi IndentationError in file generati da strumenti (es. generatori di codice), verifica il processo che genera il file.
- In progetti con contributori multipli, imposta un controllo automatico (pre-commit) per evitare commit con indentazione errata.
4 SyntaxError
Definizione breve: SyntaxError avviene quando il codice non rispetta la grammatica del linguaggio Python.
Perché succede: ogni linguaggio ha regole sintattiche. Se il parser incontra qualcosa che non riesce a interpretare, solleva SyntaxError.
Esempi comuni
- Dimenticare i due punti dopo una struttura che apre un blocco:
if x > 0
print("positivo")- Parentesi o virgolette non chiuse:
print("finestra aperta)- Parola chiave scritta male:
esleinvece dielse. - Uso non consentito di keyword come nomi di variabili.

Come interpretare il messaggio
La traccia dell’errore spesso indica la linea e la posizione approssimativa. A volte il punto mostrato può essere più in là rispetto alla vera causa (es. parentesi aperta molte righe prima). Controlla le parentesi, le virgolette e le righe precedenti.
Strumenti utili
- Linter (flake8, pylint) per catturare errori sintattici e stilistici a livello statico.
- IDE moderni che suggeriscono correzioni in tempo reale.
Esempio pratico di correzione
Errato:
def saluto(name)
print("Ciao, " + name)Corretto:
def saluto(name):
print("Ciao, " + name)Alternative e quando scegliere l’una o l’altra
- Se l’errore riguarda molteplici file, esegui prima un controllo statico su tutta la base di codice.
- Per snippet rapidi, esegui il codice in un REPL per vedere dove il parser si blocca.
3 IndexError
Definizione breve: IndexError si verifica quando si tenta di accedere a un elemento di una sequenza usando un indice fuori intervallo.
Concetto chiave: gli indici in Python sono zero-based: per una lista di N elementi gli indici validi sono 0..N-1.
Esempio:
numbers = [1, 2, 3]
print(numbers[1]) # stampa 2
print(numbers[3]) # IndexError: list index out of range
Cause comuni
- Off-by-one: iterare fino a <= len(lista) invece di < len(lista).
- Modificare (inserire/rimuovere) la lista mentre la si itera.
- Assumere che una lista non sia vuota.
Prevenzione
- Controllare la lunghezza con len()
- Usare enumerare o iterare direttamente sugli elementi (for item in lista) invece che sugli indici quando possibile.
- Per accessi che potrebbero fallire, usare try/except o controlli condizionali.
Esempi di pattern sicuri
Iterare senza indici:
for val in lista:
process(val)O con controlli:
if 0 <= idx < len(lista):
item = lista[idx]
else:
# gestire il casoQuando succede durante l’iterazione
Modificare la struttura durante la scansione può portare a comportamenti inaspettati e IndexError. Se devi rimuovere elementi, valuta di creare una nuova lista filtrata usando list comprehension.
Mini-metodologia per diagnosticare IndexError
- Identifica la lista/struttra e il valore di len() al momento dell’errore.
- Stampa l’indice usato e confrontalo con len().
- Verifica se la struttura cambia durante l’iterazione.
2 ValueError
Definizione breve: ValueError è sollevato quando un’operazione riceve un argomento del tipo corretto ma con un valore non appropriato.
Esempi tipici
- Conversione stringa->int fallita:
int('10') # ok -> 10
int('ten') # ValueError- Funzioni matematiche che richiedono valori in un certo dominio:
import math
math.sqrt(-5) # ValueError: math domain error
Perché è utile distinguere ValueError da TypeError
- TypeError: il tipo dell’argomento non è quello atteso (es.: passare una lista dove serve un numero).
- ValueError: il tipo è corretto ma il valore non è ammissibile (es.: stringa non numerica per int()).
Come gestirlo
- Usare try/except per conversioni che possono fallire.
- Validare input dell’utente prima di convertirlo.
Esempio di gestione dell’input:
try:
num = input("Inserisci un numero: ")
num_int = int(num)
except ValueError as e:
print(f"Input non valido: {e}")Suggerimenti
- Per API pubbliche, valida e documenta i formati ammessi (es. ISO date, pattern delle stringhe).
- Evita di usare eccezioni per controlli di flusso banali: preferisci validazioni esplicite quando possibile.
1 AttributeError
Definizione breve: AttributeError si verifica quando si tenta di accedere a un attributo o metodo che non esiste sull’oggetto.
Perché succede: stai chiamando un metodo su un tipo che non lo implementa, o l’oggetto è None.
Esempio:
text = "hello world"
print(text.push())Le stringhe non hanno il metodo push(), quindi Python solleva AttributeError.
Altro esempio comune:
user = None
print(user.name) # AttributeError: 'NoneType' object has no attribute 'name'
Strumenti e funzioni utili
- isinstance(obj, Tipo) per verificare il tipo.
- dir(obj) per elencare gli attributi disponibili.
Prevenzione
- Verificare None prima di accedere ad attributi: if obj is not None: …
- Usare tipizzazione statica (mypy) per ridurre errori durante lo sviluppo.
- Documentare il tipo di ritorno delle funzioni e usare annotazioni di tipo.
Pattern di codice sicuri
if hasattr(obj, 'save'):
obj.save()
else:
# fallbackQuando AttributeError indica un bug più profondo
- Se un oggetto non ha l’attributo atteso, potrebbe esserci un errore nella logica che costruisce l’oggetto (es. inizializzazione incompleta).
- In sistemi grandi, un cambiamento di API può rompere chiamate che si basano su attributi esistenti.
Checklist di prevenzione generale (Ruoli: Principiante / Team)
Per sviluppatori principianti
- Usa un editor con linting e formattazione automatica.
- Comprendi la differenza tra TypeError, ValueError e AttributeError.
- Prova snippet in REPL per capire il comportamento.
Per team e progetti
- Aggiungi pre-commit con black e flake8.
- Integra test automatici (unit test) che coprano casi limite.
- Documenta le API e i formati di input.
Casi di test e criteri di accettazione
Obiettivo: ogni errore deve essere gestito o testato nei punti critici dell’applicazione.
Esempi di test case
- IndentationError: non applicabile come test unitario diretto; assicurarsi che il linter segni file non formattati.
- SyntaxError: eseguire il parsing di moduli caricati dinamicamente e fallire in CI se sono presenti errori.
- IndexError: test per accesso a indici limite (0, len-1, len), e per liste vuote.
- ValueError: fornire input non valido e verificare che l’app gestisca l’errore restituendo un messaggio chiaro.
- AttributeError: testare con oggetti Mock privi di attributi e verificare che il codice esegua fallback o sollevi eccezioni gestite.
Criteri di accettazione (esempi)
- Il codice deve passare flake8 e mypy in CI.
- Tutti i test unitari devono coprire i casi limite per liste vuote e input non validi.
- Le API devono restituire errori di validazione chiari (HTTP 400 con messaggio) per input non conformi.
Mini-metodologia per il debug (5 passaggi)
- Leggi il messaggio di errore: identifica tipo e posizione.
- Riproduci il problema con un caso minimo riproducibile (min repro).
- Isola la sezione di codice: stampa valori, len(), type(), dir().
- Applica una correzione locale (es. controllo dei None, validazione input).
- Aggiungi test automatico che prevenga regressioni.
Diagramma di decisione per il tipo di errore (Mermaid)
flowchart TD
A[Hai un errore di runtime?] -->|No| B[Potrebbe essere SyntaxError]
A -->|Sì| C{Tipo d'errore}
C -->|Message includes 'indent'| D[IndentationError]
C -->|Message includes 'invalid syntax'| B
C -->|Message includes 'index out of range'| E[IndexError]
C -->|Message includes 'ValueError'| F[ValueError]
C -->|Message includes 'has no attribute'| G[AttributeError]
D --> H[Controlla indentazione/tab/spazi]
E --> I[Verifica len'' e iterazioni]
F --> J[Valida input e conversioni]
G --> K[Verifica tipo e dir'']Mental models e regole pratiche
- Tratta l’interprete come il primo debugger: il messaggio spesso contiene la chiave.
- Preferisci iterare su valori piuttosto che su indici quando possibile.
- Validazione preventiva: «fail fast» (rifiuta input non valido subito).
- Automatizza formattazione e controlli di stile in CI.
Glossario (1 riga per termine)
- IndentationError: errore di allineamento dei blocchi.
- SyntaxError: errore di sintassi nel codice Python.
- IndexError: accesso a indice fuori range.
- ValueError: valore non valido per l’operazione.
- AttributeError: attributo/metodo non presente sull’oggetto.
Esempi di snippet / cheat sheet rapido
- Controllo sicuro di indice:
if 0 <= idx < len(lista):
item = lista[idx]- Conversione con gestione:
try:
n = int(s)
except ValueError:
n = None # o gestisci diversamente- Verifica attributo:
if hasattr(obj, 'metodo'):
obj.metodo()- Controllo di None:
if obj is None:
# handleEdge-case gallery (quando gli accorgimenti standard non bastano)
- File generati automaticamente con indentazione errata: la soluzione è correggere il generatore o rigenerare dopo aver impostato il template.
- Input utente con spazi invisibili o caratteri Unicode che impediscono conversioni: usare strip() e normalizzazione Unicode.
- Codice che funziona in un ambiente (es. Python 3.9) ma fallisce in un altro (es. 3.6) a causa di differenze di implementazione: definire la matrix di compatibilità e i test.
Note sulla qualità e sicurezza
- Validare sempre input prima di eseguire operazioni sensibili (es. eval(), parsing di file): l’input non valido può causare non solo errori ma anche problemi di sicurezza.
Riepilogo
- Impara a interpretare i messaggi di errore: sono il primo strumento per il debug.
- Usa strumenti automatici (formatter, linters, type checker) per prevenire errori banali.
- Scrivi test che coprano casi limite (liste vuote, input malformati, None).
- Automatizza i controlli in CI per evitare regressioni di stile e sintassi.
In breve: conoscere questi 5 errori e avere una procedura di debug minimale ti farà risparmiare tempo e ridurrà i bug nel codice Python.
Short announcement:
Scopri in modo pratico i 5 errori Python più comuni e come risolverli: esempi, checklist, casi di test e una mini-metodologia di debug per evitare regressioni.