Les erreurs, c'est comme ça que Python te dit ce qui s'est passé
Chaque erreur Python est un objet avec un type, un message et un traceback — la chaîne d'appels qui y a mené. En lire un bien est la plus grande compétence de débogage que tu puisses acquérir. Cette page est un tour des erreurs que tu rencontreras vraiment, et les habitudes qui rendent leur correction rapide.
Pour un regard plus profond sur la mécanique de try/except et lever tes propres erreurs, la page Exceptions couvre la syntaxe. Cette page-ci traite des erreurs spécifiques et comment les lire.
Lire un traceback
Lance quelque chose qui casse :
def divide(a, b):
return a / b
def report(values):
for v in values:
print(divide(10, v))
report([5, 2, 0])
Python affiche quelque chose comme :
Traceback (most recent call last):
File "script.py", line 8, in <module>
report([5, 2, 0])
File "script.py", line 6, in report
print(divide(10, v))
File "script.py", line 2, in divide
return a / b
ZeroDivisionError: division by zero
Lis ça de bas en haut :
ZeroDivisionError: division by zero— le type d'exception et le message. C'est ce qui a mal tourné.return a / bàdivide, ligne 2 — la ligne qui a vraiment levé.print(divide(10, v))àreport, ligne 6 — l'appel qui l'a déclenchée.report([5, 2, 0])au niveau module, ligne 8 — où ça a commencé.
Le frame du bas, c'est presque toujours là que va le correctif. Quand une bibliothèque lève une erreur profondément dans ses internes, remonte le traceback jusqu'au premier frame dans ton code — c'est l'appel auquel tu as passé une mauvaise entrée.
Les erreurs que tu rencontreras le plus souvent
NameError
« Name 'mesage' is not defined ». Causé par des fautes de frappe ou l'utilisation d'une variable avant son affectation. Les messages d'erreur de Python nomment généralement un remplacement probable dans les versions récentes (« Did you mean 'message'? »).
Correctif : vérifie l'orthographe et la portée. Si le nom n'existe qu'à l'intérieur d'une fonction, tu ne peux pas le lire de l'extérieur.
TypeError
« Can only concatenate str (not 'int') to str ». Mauvais type pour l'opération. Classiques : ajouter une chaîne à un nombre, appeler quelque chose qui n'est pas appelable, passer le mauvais nombre d'arguments à une fonction.
Correctif : convertis les types explicitement (str(30), int("30")) ou inspecte ce que tu passes vraiment. Une f-string se lit généralement mieux que la concaténation par + à travers des types : f"age: {30}".
ValueError
« Invalid literal for int() with base 10: 'hello' ». Le type est bon — int() accepte une chaîne — mais la valeur ne colle pas. Courant avec int(), float(), le parsing datetime et les fonctions qui prennent un argument borné.
Correctif : valide avant de convertir, ou attrape l'erreur et gère-la :
KeyError
« KeyError: 'charlie' ». La clé n'est pas dans le dict. Trois correctifs idiomatiques, choisis selon l'intention :
Pour un dict où les clés manquantes devraient s'auto-initialiser, collections.defaultdict vaut un coup d'œil.
IndexError
« List index out of range ». Tu as demandé une position que la séquence n'a pas.
Correctif : protège avec un test de longueur, utilise -1 pour référencer le dernier élément, ou utilise le découpage (numbers[5:6] renvoie [] au lieu de lever).
AttributeError
« 'NoneType' object has no attribute 'upper' ». Tu as appelé une méthode sur quelque chose qui ne l'a pas. Presque toujours, ça veut dire qu'une variable est d'un type inattendu — souvent None quand tu attendais une vraie valeur.
Correctif : trouve d'où vient le None. print(type(var)) ou un breakpoint juste avant l'erreur, c'est le moyen le plus rapide. Les fonctions qui « échouent parfois » renvoient généralement None ; vérifie leur valeur de retour avant d'appeler des méthodes dessus.
ModuleNotFoundError (et ImportError)
import fastapi
« No module named 'fastapi' ». Le package n'est pas installé dans l'interpréteur Python qu'utilise ton script. Deux causes courantes :
- Tu ne l'as vraiment pas installé. Lance
python -m pip install fastapidans le bon environnement. - Tu l'as installé, mais dans un Python différent. Ça arrive sans arrêt sur macOS quand
pipetpythonpointent vers des installations différentes.
Le correctif fiable, c'est d'installer avec le même interpréteur avec lequel tu lances :
python -m pip install fastapi
Si tu utilises un environnement virtuel (et tu devrais), assure-toi qu'il est activé avant à la fois pip install et python script.py.
FileNotFoundError
with open("settings.yaml") as f:
config = f.read()
« [Errno 2] No such file or directory: 'settings.yaml' ». Le chemin n'existe pas par rapport à là où le script tourne.
Correctif : affiche os.getcwd() en haut du script pour confirmer où Python regarde. Utilise des chemins absolus ou pathlib.Path(__file__).parent / "settings.yaml" pour ancrer les chemins à l'emplacement du script lui-même.
EOFError
name = input("Name: ")
« EOF when reading a line ». input() a essayé de lire depuis stdin et n'a rien obtenu — soit l'entrée a été piped depuis une source vide, soit tu as fait Ctrl-D au prompt.
Correctif : si le piping est légitime, enveloppe l'appel :
try:
name = input("Name: ")
except EOFError:
name = "anonymous"
Dans l'éditeur navigateur de cette documentation, le runtime simule l'entrée ; tu ne rencontreras pas ça là.
IndentationError et SyntaxError
IndentationError: expected an indented block after function definition on line 2
Celles-ci sont spéciales — elles se déclenchent avant que ton programme ne tourne. Python a refusé de parser le fichier.
IndentationError— le corps d'undef,if,for, etc. est manquant ou mal aligné. La plupart des éditeurs visualisent l'indentation ; active « show whitespace » pour attraper les mélanges de tabulations et d'espaces.SyntaxError— tu as oublié un deux-points, mal apparié une parenthèse, ou mal orthographié un mot-clé. Les versions récentes de Python pointent une flèche (^) sur le caractère fautif.
Correctif : le message d'erreur nomme la ligne. Va regarder. Si rien ne semble évidemment faux sur cette ligne, vérifie la ligne au-dessus — une parenthèse non fermée quelques lignes plus haut se montre souvent comme une erreur de syntaxe bien plus tard.
RuntimeError
Un fourre-tout pour « quelque chose s'est mal passé à l'exécution qui n'est pas une des erreurs plus spécifiques ». RecursionError (profondeur de récursion dépassée) est une spécialisation courante. Le code de bibliothèque lève souvent RuntimeError quand il est dans un mauvais état.
Correctif : lis le message ; il est généralement descriptif. Si la récursion est la cause, soit convertis en boucle itérative, soit lève sys.setrecursionlimit dans de rares cas.
Débogage par print
Avant de tendre la main vers un vrai debugger, print() — ou mieux, la forme f"{var=}" — attrape la plupart des bugs :
f"{var=}" affiche à la fois la source de l'expression et sa valeur, donc tu n'as pas à retaper le nom dans la chaîne de format. Lance le script, parcours la sortie, trouve la ligne où une valeur est devenue fausse. La plupart des bugs « mystères » deviennent évidents avec trois ou quatre prints bien placés.
Nettoie les prints avant de committer. logging.debug(...) est plus sympa que print pour du code que tu vas livrer — tu peux activer et désactiver le logging debug sans éditer des lignes.
breakpoint() et pdb
Quand print ne suffit pas, breakpoint() te fait entrer dans le debugger interactif de Python à ce point :
def discount(price, percent):
breakpoint()
return price * (1 - percent / 100)
discount(100, 20)
Lance le script dans un vrai terminal. Tu atterriras à un prompt (Pdb). Quelques commandes à connaître :
p variable— affiche une variable.n— passe à la ligne suivante.s— entre dans un appel de fonction.c— continue à tourner jusqu'au prochain breakpoint ou la fin.q— quitter.l— liste le source autour de la ligne courante.
Les debuggers d'IDE (VS Code, PyCharm) enveloppent le même protocole dans une GUI — breakpoints mis dans la marge, sidebar qui montre les variables. Choisis celui qui semble le moins friction.
Habitudes qui réduisent les erreurs que tu rencontres
- Utilise des noms de variables descriptifs. La moitié du bruit
TypeErroretAttributeErrordisparaît quand tu ne peux pas oublier ce qu'il y a dans une variable. - Valide les entrées à la frontière. Parse et vérifie l'entrée utilisateur / contenu de fichier une fois, en haut de la fonction. Le reste du code peut ensuite faire confiance aux valeurs.
- Plante bruyamment, pas silencieusement. Un
except Exception: passnu cache les erreurs que tu as vraiment besoin de voir. Attrape des exceptions spécifiques, gère-les délibérément, et laisse le reste se propager. - Lis le bas du traceback en premier. Chaque minute passée à apprendre à lire les tracebacks rapporte au centuple.
La plupart des erreurs ne sont pas des mystères — ce sont des fautes de frappe d'une ligne ou des erreurs de type faux avec un message clair. Fais confiance au message d'erreur ; il a généralement raison.
Tu y es arrivé
C'est la fin de la section de référence. Tu es passé de « qu'est-ce que Python ? » à travers les variables, le contrôle de flux, les collections, les fonctions, les classes, l'itération, les données du monde réel et les erreurs. De là, les prochaines étapes sont en forme de projet : choisis quelque chose que tu veux construire et travaille à rebours vers les morceaux que tu dois apprendre plus en profondeur. Ces pages seront toujours là quand tu reviendras avec une question spécifique.
Questions fréquentes
Qu'est-ce qu'un KeyError en Python ?
KeyError est levé quand tu cherches une clé de dict qui n'existe pas. users["missing"] lève KeyError: 'missing'. Les alternatives sûres sont users.get("missing", default), users.get("missing") (renvoie None), ou un test explicite if key in users:.
Qu'est-ce qu'un EOFError en Python ?
EOFError (end-of-file) est levé quand input() ne peut rien lire parce que le flux d'entrée s'est fermé. Tu le verras le plus souvent quand un script qui utilise input() est piped sans données, ou quand tu fais Ctrl-D dans le prompt interactif. Protège avec try/except EOFError si ton script doit gérer l'entrée piped.
Qu'est-ce qu'un ModuleNotFoundError ?
ModuleNotFoundError veut dire que import X n'a pas trouvé de module nommé X. Soit le package n'est pas installé (pip install X), soit il est installé dans un Python différent de celui qui exécute ton code (très courant quand tu as plusieurs Pythons). python -m pip install X corrige le second cas en utilisant le même interpréteur.
Comment lire un traceback Python ?
Lis-le de bas en haut. La dernière ligne est le type d'exception et le message — la chose spécifique qui a mal tourné. Les lignes au-dessus montrent la pile d'appels qui y a mené, avec ton propre code généralement plus près du bas. Clique ou va au fichier + ligne dans le frame le plus bas qui est le tien ; c'est là que va le correctif.