1. Les exceptions
Quand Python rencontre un problème à l’exécution, il lève une exception et le programme s’arrête. Tu en as déjà croisé plusieurs :
| Exception | Cause typique | Exemple |
|---|---|---|
ValueError | Valeur de mauvais format | int("vingt") |
ZeroDivisionError | Division par zéro | 10 / 0 |
IndexError | Indice hors de la liste | [1, 2][5] |
KeyError | Clé absente du dictionnaire | {"a": 1}["b"] |
FileNotFoundError | Fichier introuvable | open("absent.txt") |
TypeError | Opération entre types incompatibles | "a" + 1 |
2. try / except
On place le code « risqué » dans un bloc try. Si une exception se produit, Python saute dans le bloc except correspondant au lieu de planter.
try:
age = int(input("Âge : "))
print(f"Dans 10 ans tu auras {age + 10} ans.")
except ValueError:
print("Ce n'est pas un nombre entier.")
On peut prévoir plusieurs cas et ajouter else (exécuté si tout s’est bien passé) et finally (exécuté dans tous les cas) :
try:
a = int(input("a : "))
b = int(input("b : "))
resultat = a / b
except ValueError:
print("Saisie invalide.")
except ZeroDivisionError:
print("Division par zéro impossible.")
else:
print(f"Résultat : {resultat}")
finally:
print("Fin du calcul.")
La saisie robuste, enfin
On peut maintenant terminer la fonction du niveau 4 :
def demander_entier(question, mini, maxi):
while True:
try:
n = int(input(question))
except ValueError:
print("Merci de taper un nombre entier.")
continue
if mini <= n <= maxi:
return n
print(f"Le nombre doit être entre {mini} et {maxi}.")
3. Lire et écrire des fichiers texte
La fonction open(chemin, mode) ouvre un fichier. On l’utilise toujours avec with, qui referme automatiquement le fichier, même en cas d’erreur.
| Mode | Signification |
|---|---|
"r" | Lecture (par défaut). Erreur si le fichier n’existe pas. |
"w" | Écriture. Crée le fichier ou écrase son contenu ! |
"a" | Ajout à la fin (append). Crée le fichier s’il n’existe pas. |
# Écrire
with open("journal.txt", "w", encoding="utf-8") as f:
f.write("Première ligne\n") # \n = retour à la ligne
f.write("Deuxième ligne\n")
# Ajouter
with open("journal.txt", "a", encoding="utf-8") as f:
f.write("Ligne ajoutée\n")
# Lire ligne par ligne
with open("journal.txt", "r", encoding="utf-8") as f:
for ligne in f:
print(ligne.strip()) # strip() retire le \n final
4. Le format CSV
Le CSV (valeurs séparées par des virgules ou des points-virgules) est le format des tableurs. Le module csv le gère proprement.
import csv
eleves = [
{"nom": "Alice", "note": 14},
{"nom": "Bruno", "note": 9},
]
# Écriture
with open("notes.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["nom", "note"], delimiter=";")
writer.writeheader()
writer.writerows(eleves)
# Lecture
with open("notes.csv", newline="", encoding="utf-8") as f:
for ligne in csv.DictReader(f, delimiter=";"):
print(ligne["nom"], int(ligne["note"])) # tout est lu comme du texte
Le séparateur ; permet d’ouvrir le fichier directement dans un tableur configuré en français.
5. Le format JSON
Le JSON sauvegarde facilement des listes et des dictionnaires, même imbriqués. C’est le format le plus utilisé pour échanger des données sur le web.
import json
contacts = {"Léo": {"tel": "0600000000", "email": "leo@exemple.fr"}}
with open("contacts.json", "w", encoding="utf-8") as f:
json.dump(contacts, f, indent=2, ensure_ascii=False)
with open("contacts.json", encoding="utf-8") as f:
contacts = json.load(f)
Gérer le fichier absent
def charger(chemin):
try:
with open(chemin, encoding="utf-8") as f:
return json.load(f)
except FileNotFoundError:
return {} # premier lancement : rien à charger
except json.JSONDecodeError:
print("Fichier corrompu, démarrage à vide.")
return {}
6. Mini-projet : les contacts persistants
7. Bilan
Exercices corrigés
La robustesse se teste en essayant de casser son programme : taper du texte, rien du tout, des nombres négatifs, supprimer le fichier de données, le corrompre… Un programme bien écrit survit à tout cela.
Exercice 6.1 — Blinder ses programmes
Voir le corrigé
import random
secret = random.randint(1, 100)
essais = 0
while True:
try:
prop = int(input("Proposition : "))
except ValueError:
print("Un nombre entier, s'il te plaît.")
continue
essais += 1
if prop < secret:
print("Plus grand")
elif prop > secret:
print("Plus petit")
else:
print(f"Gagné en {essais} essais !")
break
Explication
continue renvoie au début de la boucle sans compter l’essai : une faute de frappe ne pénalise pas le joueur. Seul int() est dans le try, pour ne pas masquer d’autres erreurs.
Pour aller plus loin
La calculatrice blindée (seule la fonction de saisie change) :
def demander_nombre(question):
while True:
try:
return float(input(question).replace(",", "."))
except ValueError:
print("Nombre invalide, recommence.")
Le replace(",", ".") accepte aussi la virgule française : une petite attention qui améliore beaucoup l’expérience utilisateur.
Exercice 6.2 — Journal de bord
Voir le corrigé
from datetime import datetime
FICHIER = "journal.txt"
try:
with open(FICHIER, encoding="utf-8") as f:
lignes = f.readlines()
for ligne in lignes[-5:]:
print(ligne.strip())
except FileNotFoundError:
print("Journal vide.")
phrase = input("Nouvelle entrée : ")
horodatage = datetime.now().strftime("%d/%m/%Y %H:%M")
with open(FICHIER, "a", encoding="utf-8") as f:
f.write(f"[{horodatage}] {phrase}\n")
Explication
On lit d’abord (s’il existe) puis on ajoute avec le mode "a". readlines() renvoie une liste de lignes ; la tranche [-5:] garde les 5 dernières, même s’il y en a moins.
Mini-projet
Voir le corrigé
import json, csv
from datetime import datetime
FICHIER = "contacts.json"
def charger():
try:
with open(FICHIER, encoding="utf-8") as f:
return json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
return {}
def sauvegarder(contacts):
with open(FICHIER, "w", encoding="utf-8") as f:
json.dump(contacts, f, indent=2, ensure_ascii=False)
def journaliser(action):
date = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
with open("historique.log", "a", encoding="utf-8") as f:
f.write(f"{date} {action}\n")
def exporter_csv(contacts):
with open("contacts.csv", "w", newline="", encoding="utf-8") as f:
w = csv.writer(f, delimiter=";")
w.writerow(["nom", "tel", "email"])
for nom, c in sorted(contacts.items()):
w.writerow([nom, c["tel"], c["email"]])
print("Export terminé : contacts.csv")
# Dans main() : contacts = charger() au début,
# puis sauvegarder(contacts) et journaliser("ajout Léo")
# après chaque ajout ou suppression.
Explication
Le principe est de sauvegarder après chaque modification : en cas de coupure, rien n’est perdu. Voici le programme complet assemblé.
Pour aller plus loin
def main():
contacts = charger()
while True:
choix = input("\n1 Ajouter 2 Afficher 3 Rechercher 4 Supprimer 5 Export CSV 6 Quitter > ")
if choix == "1":
nb_avant = len(contacts)
ajouter(contacts) # fonction du niveau 5
if len(contacts) > nb_avant:
sauvegarder(contacts)
journaliser("ajout")
elif choix == "2":
afficher(contacts)
elif choix == "3":
rechercher(contacts)
elif choix == "4":
nb_avant = len(contacts)
supprimer(contacts)
if len(contacts) < nb_avant:
sauvegarder(contacts)
journaliser("suppression")
elif choix == "5":
exporter_csv(contacts)
elif choix == "6":
break
else:
print("Choix inconnu.")
main()
Le journal note seulement le type d’action et pas le contenu : c’est un bon principe de minimisation des données (RGPD).
🧠 Testez vos connaissances
5 questions. Répondez puis cliquez sur « Corriger ». Rien n’est enregistré : c’est de l’auto-évaluation.
© 2026 Bruno Jousseaume. Ce cours est publié sous licence CC BY-NC-SA 4.0 : vous pouvez le partager et l’adapter en citant l’auteur et un lien vers cette page, sans usage commercial, et en partageant vos adaptations sous la même licence.