Écriture et création de fichiers en Python
Apprenez à écrire des fichiers en Python : write(), writelines(), mode append, écriture binaire, pathlib, encodage et patterns sûrs avec with.
L'écriture de fichiers est l'une des opérations d'E/S les plus fondamentales en Python. Que vous sauvegardiez la sortie d'un programme, persisiez une configuration, exportiez des données au format CSV ou journalisiez des événements, vous avez besoin d'un moyen fiable pour créer et mettre à jour des fichiers. Ce chapitre couvre toutes les approches que Python propose : write(), writelines(), le mode append, les écritures binaires, la gestion des sauts de ligne, l'encodage des caractères, l'API moderne pathlib, et les patterns pour écrire en toute sécurité sans perte de données.
Ouvrir un fichier en écriture
Toute opération d'écriture commence par la fonction intégrée open(). Le deuxième argument — le mode — contrôle ce qui se passe à l'ouverture du fichier :
| Mode | Signification | Fichier existant | Fichier absent |
|---|---|---|---|
"w" | Écriture (texte) | Tronque (efface) le fichier | Crée un nouveau fichier |
"a" | Ajout (texte) | Déplace le pointeur en fin | Crée un nouveau fichier |
"x" | Création exclusive | Lève FileExistsError | Crée un nouveau fichier |
"wb" | Écriture (binaire) | Tronque le fichier | Crée un nouveau fichier |
"ab" | Ajout (binaire) | Déplace le pointeur en fin | Crée un nouveau fichier |
"r+" | Lecture + écriture | Ouvre sur place | Lève FileNotFoundError |
La chose la plus importante à retenir concernant le mode "w" : il efface silencieusement l'intégralité du fichier avant l'écriture. Si vous souhaitez uniquement ajouter du contenu à un fichier existant, utilisez plutôt le mode "a" (append).
Fournissez toujours le paramètre encoding lors de l'écriture de fichiers texte afin que votre code se comporte de manière identique sous Windows, macOS et Linux :
file = open("output.txt", "w", encoding="utf-8")Toujours utiliser un bloc with
Appeler open() sans bloc with signifie que vous devez appeler file.close() vous-même. Oublier de fermer un fichier entraîne des données tamponnées qui ne sont jamais écrites sur le disque, des erreurs de trop nombreux fichiers ouverts dans des scripts à longue durée de vie, et une corruption du fichier sur certains systèmes d'exploitation.
L'instruction with (un gestionnaire de contexte) résout tous ces problèmes. Python ferme le fichier automatiquement à la sortie du bloc — même si une exception est levée à l'intérieur du bloc.
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Hello, World!\n")
# File is closed and flushed here — guaranteedTous les exemples de ce chapitre utilisent l'instruction with. Évitez le pattern manuel open() / close().
Écrire du texte avec write()
file.write(string) écrit la chaîne donnée dans le fichier et retourne le nombre de caractères écrits. Elle n'ajoute pas de saut de ligne automatiquement — vous devez inclure \n vous-même.
Écrire une seule ligne dans un nouveau fichier
with open("greeting.txt", "w", encoding="utf-8") as f:
chars_written = f.write("Hello, World!\n")
print(chars_written) # 14Écrire plusieurs lignes en appelant write() de manière répétée
with open("poem.txt", "w", encoding="utf-8") as f:
f.write("Roses are red,\n")
f.write("Violets are blue,\n")
f.write("Python is great,\n")
f.write("And so are you.\n")Chaque appel à write() écrit à la position actuelle dans le fichier. Le fichier est réécrit depuis le début (tout contenu précédent est supprimé) car le mode "w" a été utilisé.
Écrire plusieurs lignes avec writelines()
file.writelines(iterable) accepte tout itérable de chaînes — une liste, un générateur ou un tuple — et écrit chaque élément en séquence. Comme write(), elle n'ajoute pas de sauts de ligne entre les éléments.
Écrire une liste de lignes
lines = [
"First line\n",
"Second line\n",
"Third line\n",
]
with open("lines.txt", "w", encoding="utf-8") as f:
f.writelines(lines)Si vos données source ne contiennent pas déjà \n, ajoutez-le avant l'écriture :
data = ["Alice", "Bob", "Charlie"]
with open("names.txt", "w", encoding="utf-8") as f:
f.writelines(name + "\n" for name in data)L'expression génératrice name + "\n" for name in data est efficace en mémoire : Python produit chaque chaîne à la demande au lieu de construire toute la liste en mémoire au préalable.
write() vs writelines() — Quand utiliser lequel
write() | writelines() | |
|---|---|---|
| Entrée | Une seule chaîne | Tout itérable de chaînes |
| Sauts de ligne | Vous contrôlez chaque \n | Vous contrôlez chaque \n |
| Idéal pour | Construire la sortie de manière incrémentale | Écrire une séquence pré-construite en une fois |
Créer un fichier qui ne doit pas déjà exister
Utilisez le mode "x" (création exclusive) lorsque vous voulez que Python crée un nouveau fichier et échoue si le fichier existe déjà. Cela évite d'écraser accidentellement des données importantes.
try:
with open("config.txt", "x", encoding="utf-8") as f:
f.write("host=localhost\n")
f.write("port=8080\n")
except FileExistsError:
print("config.txt already exists — not overwriting.")Ce pattern est utile pour générer des fichiers de sortie uniques (journaux, exports, snapshots) où une collision indique qu'il s'est passé quelque chose d'anormal.
Ajouter du contenu à un fichier existant
Ouvrir un fichier avec le mode "a" déplace le pointeur d'écriture à la fin du fichier. Le nouveau contenu est ajouté après le contenu existant ; rien n'est effacé.
Ajouter une entrée de journal à un fichier existant
import datetime
with open("app.log", "a", encoding="utf-8") as f:
timestamp = datetime.datetime.now().isoformat()
f.write(f"[{timestamp}] Server started\n")Si app.log n'existe pas encore, Python le crée. S'il existe, la nouvelle ligne est ajoutée à la fin. Exécuter le script plusieurs fois accumule un journal croissant.
Écriture vs ajout — Choisir le bon mode
- Utilisez
"w"lorsque vous souhaitez remplacer entièrement le contenu du fichier (générer un nouveau rapport, sauvegarder une nouvelle configuration). - Utilisez
"a"lorsque vous souhaitez ajouter au contenu existant (journalisation, accumulation de résultats sur plusieurs exécutions).
Sauts de ligne et fins de ligne
Le mode texte de Python ("w", "a", "r") traduit le saut de ligne universel \n vers la fin de ligne native de la plateforme à l'écriture :
- Windows :
\n→\r\n(CRLF) - macOS / Linux :
\nreste\n(LF)
C'est généralement le bon comportement — les fichiers écrits sous Windows s'ouvrent correctement dans le Bloc-notes.
Si vous devez forcer une fin de ligne spécifique quelle que soit la plateforme — par exemple, lors de la génération de fichiers devant être lus par un système particulier — passez le paramètre newline :
# Force Unix-style LF on all platforms (e.g. for Linux-target files)
with open("unix_file.txt", "w", encoding="utf-8", newline="\n") as f:
f.write("line one\n")
f.write("line two\n")
# Preserve line endings exactly as given (no translation at all)
with open("raw.txt", "w", encoding="utf-8", newline="") as f:
f.write("line one\r\n")
f.write("line two\n")Encodage des caractères
Spécifiez toujours encoding= lors de l'écriture de fichiers texte. Se fier à la valeur par défaut de la plateforme risque de créer des fichiers illisibles sur d'autres systèmes.
Encodages recommandés pour les scénarios courants :
| Encodage | Utiliser quand |
|---|---|
"utf-8" | Usage général ; fonctionne pour toutes les langues ; par défaut pour la plupart des projets Python |
"utf-8-sig" | UTF-8 avec BOM — utile pour les fichiers qui seront ouverts dans Excel sous Windows |
"latin-1" | Fichiers hérités d'Europe occidentale |
"cp1252" | Texte Windows ANSI |
Écrire un fichier avec l'encodage UTF-8
with open("international.txt", "w", encoding="utf-8") as f:
f.write("English: Hello\n")
f.write("Japanese: こんにちは\n")
f.write("Arabic: مرحبا\n")Écriture de fichiers binaires
Ouvrez un fichier avec le mode "wb" (écriture binaire) pour écrire des octets bruts au lieu de chaînes. Le mode binaire est requis pour les images, l'audio, les archives compressées, les exécutables et toute donnée non textuelle. Ne spécifiez pas encoding en mode binaire.
Écrire des octets dans un fichier binaire
data = bytes([0x89, 0x50, 0x4E, 0x47]) # PNG magic bytes
with open("header.bin", "wb") as f:
f.write(data)
print(f.write(b"\r\n\x1a\n")) # 4Copier un fichier binaire
with open("photo.jpg", "rb") as src:
content = src.read()
with open("photo_backup.jpg", "wb") as dst:
dst.write(content)Pour les grands fichiers binaires, lisez et écrivez par morceaux pour éviter de charger l'intégralité du fichier en mémoire :
CHUNK = 65536 # 64 KB
with open("large.bin", "rb") as src, open("large_copy.bin", "wb") as dst:
while True:
chunk = src.read(CHUNK)
if not chunk:
break
dst.write(chunk)Gestion des erreurs lors de l'écriture
Un script de qualité production anticipe toujours les façons dont une écriture de fichier peut échouer.
Gérer les erreurs d'écriture courantes
try:
with open("/etc/protected.txt", "w", encoding="utf-8") as f:
f.write("data\n")
except PermissionError:
print("Error: you do not have write permission for this file.")
except FileNotFoundError:
print("Error: one or more directories in the path do not exist.")
except IsADirectoryError:
print("Error: the path points to a directory, not a file.")
except OSError as e:
print(f"OS error: {e}")Exceptions courantes que vous rencontrerez :
| Exception | Quand elle se produit |
|---|---|
PermissionError | Le processus ne dispose pas des droits d'écriture |
FileNotFoundError | Un répertoire intermédiaire dans le chemin n'existe pas |
FileExistsError | Mode "x" et le fichier existe déjà |
IsADirectoryError | Le chemin pointe vers un répertoire |
OSError | Disque plein, erreur de système de fichiers réseau et autres problèmes au niveau OS |
Consultez Python Try Except pour un guide complet sur la gestion des exceptions.
Écriture sécurisée de fichiers (pattern d'écriture atomique)
Un simple open("file.txt", "w") n'est pas sûr pour les données critiques : si votre script plante ou est interrompu en cours d'écriture, le fichier se retrouve dans un état partiellement écrit et corrompu. La solution standard est une écriture atomique : écrire d'abord dans un fichier temporaire, puis le renommer par-dessus la cible.
import os
import tempfile
def write_file_safely(path, content, encoding="utf-8"):
"""Write content to path atomically using a temp file + rename."""
dir_name = os.path.dirname(os.path.abspath(path)) or "."
# Write to a temp file in the same directory (same filesystem = atomic rename)
fd, tmp_path = tempfile.mkstemp(dir=dir_name)
try:
with os.fdopen(fd, "w", encoding=encoding) as f:
f.write(content)
os.replace(tmp_path, path) # atomic on POSIX; best-effort on Windows
except Exception:
os.unlink(tmp_path) # clean up if something went wrong
raise
write_file_safely("important.txt", "critical data\n")os.replace() (Python 3.3+) remplace la destination de manière atomique sur les systèmes POSIX : les lecteurs voient soit l'ancien fichier, soit le nouveau, jamais une écriture partielle.
Écriture de fichiers avec pathlib
pathlib.Path (introduit dans Python 3.4) fournit une API concise et orientée objet. Pour les écritures simples en une seule opération, Path.write_text() et Path.write_bytes() sont plus lisibles que open().
Path.write_text()
from pathlib import Path
Path("output.txt").write_text("Hello from pathlib!\n", encoding="utf-8")write_text() ouvre le fichier en mode "w", écrit la chaîne et ferme le fichier — le tout en un seul appel. Il écrase toujours le fichier. Il n'existe pas d'équivalent pour l'ajout ; pour ajouter, utilisez open() avec le mode "a".
Path.write_bytes()
from pathlib import Path
Path("data.bin").write_bytes(b"\x00\x01\x02\x03")Construire des chemins avec pathlib
pathlib facilite également la construction de chemins en toute sécurité sans concaténation de chaînes :
from pathlib import Path
output_dir = Path("results")
output_dir.mkdir(exist_ok=True) # create the directory if needed
report_path = output_dir / "report.txt"
report_path.write_text("Run complete.\n", encoding="utf-8")
print(report_path) # results/report.txt
print(report_path.exists()) # TrueL'opérateur / sur les objets Path joint les segments de chemin — pas besoin de os.path.join().
Exemple pratique : écrire un rapport CSV
L'exemple complet suivant écrit une liste d'enregistrements dans un fichier CSV en utilisant uniquement des outils intégrés (sans le module csv), illustrant plusieurs concepts de ce chapitre ensemble.
from pathlib import Path
import datetime
def write_csv_report(path, headers, rows):
"""Write a simple CSV file with a header row."""
with open(path, "w", encoding="utf-8", newline="") as f:
f.write(",".join(headers) + "\n")
for row in rows:
f.write(",".join(str(v) for v in row) + "\n")
records = [
("Alice", 30, "Engineering"),
("Bob", 25, "Marketing"),
("Charlie", 35, "Finance"),
]
output = Path("staff_report.txt")
write_csv_report(output, ["Name", "Age", "Department"], records)
print(output.read_text(encoding="utf-8"))Sortie attendue :
Name,Age,Department
Alice,30,Engineering
Bob,25,Marketing
Charlie,35,FinanceNotez que newline="" est passé à open() pour que Python ne double-traduise pas les fins de ligne à l'intérieur des lignes CSV — cela correspond à la recommandation de la documentation du module csv de Python.
Pour tout ce qui est plus complexe (guillemets, dialectes, cas limites Unicode), utilisez plutôt le module intégré Python CSV.
Référence rapide
| Objectif | Pattern de code |
|---|---|
| Créer ou écraser un fichier | open("f.txt", "w", encoding="utf-8") |
| Ajouter à un fichier | open("f.txt", "a", encoding="utf-8") |
| Créer uniquement si nouveau | open("f.txt", "x", encoding="utf-8") |
| Écrire des données binaires | open("f.bin", "wb") |
| Écrire une seule chaîne | f.write("text\n") |
| Écrire une liste de chaînes | f.writelines(lines) |
| Écriture texte en une fois | Path("f.txt").write_text("...", encoding="utf-8") |
| Écriture binaire en une fois | Path("f.bin").write_bytes(b"...") |
| Écriture sûre / atomique | Écrire dans un fichier temporaire, puis os.replace() |
Chapitres connexes
- Python File Handling — modes d'ouverture, paramètres de
open()et instructionwith - Python Read Files —
read(),readline(),readlines(), itération sur les lignes etseek() - Python Delete Files — suppression sécurisée de fichiers et répertoires
- Python Try Except — gestion des exceptions en Python
- Python CSV — lecture et écriture de fichiers CSV avec le module
csv - Python JSON — sérialisation de données en fichiers JSON