Cours de Python / Lire et écrire des fichiers texte avec with et UTF-8
Pour lire ou écrire un fichier texte, indiquez son encodage et utilisez with pour fermer le fichier à la sortie du bloc. Le mode w tronque un fichier existant dès son ouverture : créer un nouveau résultat et remplacer des données à conserver demandent des choix différents.
Choisir le mode et l’encodage
| Mode | Usage | Comportement |
|---|---|---|
r |
Lire | Échoue si le fichier n’existe pas |
w |
Écrire un contenu de remplacement | Tronque l’existant, ou crée le fichier |
a |
Ajouter à la fin | Conserve l’existant, ou crée le fichier |
x |
Créer exclusivement | Échoue si le chemin existe déjà |
L’encodage définit comment les caractères sont représentés par des octets. Pour un texte UTF-8, écrivez explicitement encoding="utf-8" ; cela rend le contrat visible et évite de dépendre d’un défaut qui peut varier avec la version ou la configuration de l’environnement. Un fichier d’un autre encodage doit être identifié puis lu avec cet encodage, pas supposé UTF-8.
errors="ignore" peut faire disparaître les octets impossibles à décoder. Ce n’est pas un remède général à une erreur d’encodage : vous risqueriez de masquer une perte de données. La documentation Python sur la lecture et l’écriture de fichiers présente les modes texte et binaire ainsi que la fermeture avec with.
Écrire, compléter puis lire un fichier complet
Utilisez un dossier d’exercice réservé aux essais. Ce programme réinitialise notes-demo.txt en mode w à chaque lancement ; ne le placez pas à côté d’un fichier de même nom que vous souhaitez conserver. Python 3 et sa bibliothèque standard suffisent.
Enregistrez le bloc complet ci-dessous dans text_files.py, en UTF-8. Ouvrez le terminal dans ce dossier avec l’environnement virtuel du projet activé puis lancez python text_files.py. Sur macOS ou Ubuntu hors environnement virtuel, utilisez python3 text_files.py si votre interpréteur porte ce nom.
from pathlib import Path
path = Path("notes-demo.txt")
with path.open("w", encoding="utf-8", newline="\n") as f:
f.write("coffee:3500\n")
f.write("lunch:8000\n")
with path.open("a", encoding="utf-8") as f:
f.write("bus:2500\n")
with path.open("r", encoding="utf-8") as f:
for line in f:
print(line.rstrip("\n"))
Le résultat attendu est :
coffee:3500
lunch:8000
bus:2500
Le premier bloc with écrit les deux premières lignes et ferme le fichier. Le deuxième le rouvre en ajout pour écrire bus:2500. Le dernier le lit ligne par ligne ; rstrip("\n") retire la fin de ligne avant que print ajoute la sienne. Ouvrez aussi notes-demo.txt dans un éditeur pour contrôler les trois enregistrements réellement écrits.
Dans cette version, la première ouverture impose des fins de ligne LF avec newline="\n", tandis que l’ouverture en ajout utilise la règle par défaut de la plateforme. Sous Windows, la dernière ligne peut donc être écrite avec CRLF et les premières avec LF. La lecture texte par défaut normalise ces fins de ligne et l’affichage reste identique. Pour imposer des LF partout dans une variante, appliquez aussi newline="\n" à l’ouverture en ajout. Les paramètres d’open précisent cette conversion.
Choisir la lecture globale ou ligne par ligne
f.read() sans taille lit le contenu restant dans une chaîne. for line in f permet de traiter une ligne à la fois sans charger volontairement tout le fichier en mémoire. Lorsque le curseur atteint la fin, une nouvelle lecture renvoie une chaîne vide ; rouvrez le fichier ou utilisez explicitement seek(0) avant de recommencer depuis le début.
Le contexte with ferme le fichier à la sortie du bloc, y compris si une exception survient. L’objet f peut encore porter un nom après ce bloc, mais il est fermé : lire dessus provoque une erreur. Cette fermeture libère la ressource ; elle n’est ni une sauvegarde ni une annulation des écritures déjà effectuées.
strip() retire aussi les espaces de début et de fin, qui peuvent appartenir aux données. rstrip("\n") limite ici le retrait au saut de ligne normalisé par l’ouverture texte. Si vous changez les règles de newline pour conserver les terminaisons brutes, vérifiez à nouveau ce nettoyage au lieu de supposer que chaque ligne se termine de la même façon.
Protéger les originaux et diagnostiquer les erreurs
Une FileNotFoundError demande de vérifier le chemin réel et le dossier parent ; une UnicodeDecodeError demande de vérifier l’encodage effectif ; une PermissionError peut venir des droits ou d’un verrouillage. Un dossier utilisé à la place d’un fichier peut produire une erreur dont le type dépend du système. La leçon sur les chemins avec pathlib aide à identifier la destination.
Ne transformez pas toutes ces erreurs en une chaîne vide : cela confondrait un fichier absent, un fichier illisible et un fichier réellement vide. Pour des données importantes, prévoyez une sauvegarde et, selon le besoin, une écriture vers un fichier temporaire distinct, une validation puis un remplacement maîtrisé. Une erreur après une ouverture en w peut laisser l’ancien contenu déjà perdu ; with ne le restaure pas.
- Exécutez deux fois le programme initial : chaque lancement doit afficher les mêmes trois lignes, car l’ouverture initiale en w réinitialise le fichier.
- Changez uniquement le premier mode w en a, puis relancez depuis le fichier de trois lignes déjà créé. Les trois nouvelles lignes s’ajoutent aux précédentes : le fichier en contient six. Un autre lancement en contiendrait neuf.
- Restaurez w et relancez une fois : le fichier revient aux trois lignes de référence. Vérifiez le contenu avec l’éditeur, et pas uniquement la console.




