Il y a quelques années, un stagiaire m'appelle au secours : son petit script de facturation refuse de démarrer. Il me montre son écran, plein de rouge. Je regarde trente secondes. Il avait tapé if age = 18: au lieu de if age == 18:. Deux signes égaux qui manquent, et une heure de panique pour rien.
J'ai vu cette scène se rejouer une bonne dizaine de fois depuis. Pas dans la même entreprise, pas avec le même code, mais toujours ce même visage déçu devant Python qui refuse de coopérer. Quand on débute, on imagine que les erreurs courantes en programmation Python sont des pièges exotiques. En réalité, ce sont presque toujours les cinq ou six mêmes, qui reviennent en boucle.
Je n'ai pas de diplôme d'informatique. J'ai appris Python sur le tas, par besoin, et j'ai longuement galéré. Ce qui a fini par me débloquer, ce n'est pas un cours de plus — c'est d'arrêter de voir mes erreurs comme des punitions et de commencer à les lire comme des messages. Voilà ce que j'ai retenu, avec le détail des fautes qui m'ont coûté le plus de temps.
Points clés à retenir
- Confondre
=(affectation) et==(comparaison) reste l'erreur n°1, et Python la signale clairement. - Les erreurs ne sont pas de même nature : syntaxe, exécution, logique. Chacune se diagnostique autrement.
- La gestion des erreurs avec
try/excepts'apprend tôt, pas à la fin. - Un programme qui tourne n'est pas forcément un programme correct — c'est tout le piège de l'erreur logique.
- Lire une trace d'appel de bas en haut fait gagner un temps fou.
- Nommer ses variables et ses fonctions comme des phrases complètes réduit la charge mentale plus qu'on ne le croit.
Erreur de syntaxe Python : le réflexe du message en rouge
Python est un langage exigeant sur la forme. Une virgule oubliée, une parenthèse qui ne se ferme pas, une chaîne de caractères non terminée, et le programme entier refuse de se lancer. La bonne nouvelle, c'est que l'interpréteur vous dit exactement où il a abandonné.
Le signe égal : pourquoi = n'est pas ==
Le cas du stagiaire, c'est le classique. En Python, un seul = range une valeur dans une variable. Deux == comparent deux valeurs et renvoient True ou False. Mélanger les deux, c'est écrire une phrase grammaticalement impossible, et Python s'arrête net :
age = 18 # je range 18 dans age
if age == 18: # je vérifie SI age vaut 18
print("majeur") J'ai mis un bon mois à ne plus faire cette faute. Pas parce que le concept était dur — parce que la frappe s'installe dans les doigts et que le cerveau lit ce qu'il croit avoir écrit, pas ce qui est vraiment à l'écran.
L'indentation : le détail qui change tout
Beaucoup de langages se moquent de vos espaces. Python, non. C'est l'indentation qui délimite les blocs. Une ligne mal décalée et tout part de travers.
- Espaces ou tabulations : choisissez-en un et tenez-vous-y. En général quatre espaces.
- Une ligne de code qui devrait être dans un
ifmais qui reste collée à gauche passe à la trappe sans erreur — et là, c'est le bug silencieux. - Un bloc vide fait planter Python, il faut mettre
passpour dire « rien pour l'instant ».
Encore aujourd'hui, je reconnais une indentation douteuse au premier coup d'œil dans mes anciens fichiers. C'est un peu comme relire une lettre où l'on devine qu'on était fatigué.
Erreurs d'exécution : quand le programme démarre puis s'écrase
Différence cruciale, et souvent mal comprise au début : une erreur de syntaxe empêche le lancement, une erreur d'exécution (une exception) arrive en plein milieu, alors que le code tourne déjà. Vous ouvrez un fichier qui n'existe pas. Vous divisez par zéro. Vous demandez à Python de lire un index qui n'est pas là. Il lève alors une exception avec un nom précis.
Comment lire une trace d'appel sans paniquer
La fameuse trace d'appel (traceback) fait peur, mais elle se lit de bas en haut. La dernière ligne est la vraie cause. Au-dessus, vous trouvez le numéro de ligne où ça a explosé, dans votre code, pas dans celui des autres.
- Regardez d'abord la dernière ligne : type d'erreur et message.
- Remontez pour trouver le fichier et le numéro de ligne qui vous concernent.
- Ignorez le reste tant que vous ne comprenez pas l'essentiel.
Ça m'a pris un moment pour l'admettre : je lisais mes traces à l'envers, du haut vers le bas, en cherchant le début. Dès que j'ai inversé le sens, mes sessions de débogage ont raccourci.
try/except : attraper plutôt que subir
La gestion des erreurs n'est pas un chapitre avancé à garder pour plus tard. Elle vous permet d'anticiper le plantage et de continuer à faire quelque chose d'utile.
try:
age = int(input("Votre âge : "))
except ValueError:
print("Ce n'est pas un nombre entier.") Deux pièges pourtant : un except trop large qui avale tout, et le fameux « j'attrape mais je ne fais rien ». Ce n'est pas des erreurs de débutant qu'on corrige une fois pour toutes — c'est un réflexe à surveiller en continu.
Erreurs logiques : le programme tourne, mais raconte n'importe quoi
Les plus dangereuses n'ont pas de message. Python exécute votre code sans broncher, vous obtenez un résultat, et ce résultat est faux. Comme il n'y a rien de rouge, on ne cherche pas. Et le bug s'installe.
La valeur par défaut qui se souvient de tout
Mon pire souvenir de ce genre : une fonction pour ajouter des lignes à une liste. Je l'appelais plusieurs fois, et les résultats d'appels précédents traînaient dedans. J'ai mis une soirée à comprendre que le problème venait de la valeur par défaut de l'argument.
def ajouter(nom, liste=[]):
liste.append(nom)
return liste
print(ajouter("A")) # ['A']
print(ajouter("B")) # ['A', 'B'] ← pas ce qu'on veut Python ne recrée pas la liste vide à chaque appel : il garde celle qu'il a fabriquée une seule fois, quand il a lu la définition de la fonction. La correction est d'utiliser None par défaut et de créer la liste à l'intérieur. Une fois qu'on connaît le mécanisme, on ne se fait plus jamais avoir.
Nommer ses variables : le vrai confort
Écrire a, tmp, data2. Je l'ai fait. Puis j'ai rouvert un fichier trois mois plus tard et j'ai relu chaque ligne comme un texte étranger. Depuis, j'écris solde_client, lignes_importees, date_echeance. Un nom qui prend cinq secondes de plus à taper en économise plusieurs minutes.
C'est aussi ce qui rend le code maintenable : quelqu'un d'autre — ou vous-même dans six mois — doit pouvoir le lire avant de le modifier. Les outils de vérification automatique (les linters) rappellent d'ailleurs ces bonnes habitudes, et la convention PEP 8 précise la plupart des cas.
Tableau récapitulatif : quelle erreur vous avez probablement devant les yeux
Je regroupe ici les erreurs qui reviennent le plus souvent, avec le diagnostic express. Gardez-le sous la main quand quelque chose cloche.
| Erreur courante | Ce que vous voyez | La cause probable |
|---|---|---|
= au lieu de == | SyntaxError au lancement | Vous affectez au lieu de comparer |
| Indentation incohérente | IndentationError ou comportement étrange | Espaces et tabulations mélangés, ou bloc mal délimité |
| Index hors limites | IndexError en cours d'exécution | Vous demandez un élément qui n'existe pas |
| Type non attendu | TypeError | Par exemple, concaténer un texte et un nombre |
| Valeur par défaut mutable | Aucune erreur, résultat bizarre | La liste partagée se souvient des appels précédents |
| Variable non définie | NameError | Faute de frappe ou ordre d'écriture inversé |
Aucune ligne de ce tableau ne relève d'un savoir réservé aux experts. Ce sont toutes des situations que j'ai rencontrées, certaines plusieurs fois.
Une méthode concrète pour ne plus tourner en rond
Quand ça plante, la tentation est de modifier une ligne, relancer, modifier encore, relancer. C'est le chemin le plus long. La démarche qui m'a le plus servi tient en quatre temps, dans cet ordre :
- Analyser — relire le message d'erreur en entier, comprendre ce qui était attendu et ce qui a été fourni.
- Formuler — décrire en une phrase ce que le programme devait faire.
- Corriger — modifier un seul endroit à la fois, pas trois à la fois.
- Valider — relancer, retester le cas normal et le cas limite (par exemple, une saisie vide).
L'étape que je sautais systématiquement, c'est la deuxième. Décrire l'objectif en une phrase. C'est bête, mais quand j'écris « ce script doit additionner les montants TTC et afficher le total », je vois tout de suite si ma ligne fait autre chose.
Faut-il utiliser un débogueur, ou le bon vieux print ?
Les deux, et sans états d'âme. Le print reste parfait pour vérifier qu'une variable vaut bien ce qu'on croit à un moment donné, et je m'en sers encore tous les jours. Le débogueur intégré à l'éditeur, lui, permet de mettre le programme en pause et d'avancer ligne par ligne en observant les valeurs. Sur un bug vraiment coriace, cette fonctionnalité économise une quantité impressionnante de print disparates.
Faut-il apprendre Python en cherchant d'abord à éviter les erreurs ?
Non, et je dirais même l'inverse. Vous allez faire des erreurs. C'est la seule façon d'apprendre. Ce qu'il faut, c'est apprendre à les lire. Un débutant qui lit un message d'erreur jusqu'au bout, calmement, progresse deux fois plus vite qu'un débutant qui recopie une solution trouvée ailleurs sans comprendre ce qui clochait dans la sienne.
J'ai appris Python comme ça, sans plan de carrière, un besoin après l'autre. Ce qui compte, ce n'est pas d'écrire un programme parfait du premier coup. C'est de reconnaître, au bout d'un moment, ce que Python essaie de vous dire — et de ne plus voir ce message comme une sanction, mais comme quelqu'un qui vous tend une carte du problème.
La prochaine fois qu'une ligne rouge apparaît dans votre console, lisez la dernière ligne d'abord. Vous serez peut-être déjà à moitié sur la piste.