W3docs

É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 :

ModeSignificationFichier existantFichier absent
"w"Écriture (texte)Tronque (efface) le fichierCrée un nouveau fichier
"a"Ajout (texte)Déplace le pointeur en finCrée un nouveau fichier
"x"Création exclusiveLève FileExistsErrorCrée un nouveau fichier
"wb"Écriture (binaire)Tronque le fichierCrée un nouveau fichier
"ab"Ajout (binaire)Déplace le pointeur en finCrée un nouveau fichier
"r+"Lecture + écritureOuvre sur placeLè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 — guaranteed

Tous 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éeUne seule chaîneTout itérable de chaînes
Sauts de ligneVous contrôlez chaque \nVous contrôlez chaque \n
Idéal pourConstruire 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 : \n reste \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 :

EncodageUtiliser 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"))   # 4

Copier 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 :

ExceptionQuand elle se produit
PermissionErrorLe processus ne dispose pas des droits d'écriture
FileNotFoundErrorUn répertoire intermédiaire dans le chemin n'existe pas
FileExistsErrorMode "x" et le fichier existe déjà
IsADirectoryErrorLe chemin pointe vers un répertoire
OSErrorDisque 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())  # True

L'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,Finance

Notez 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

ObjectifPattern de code
Créer ou écraser un fichieropen("f.txt", "w", encoding="utf-8")
Ajouter à un fichieropen("f.txt", "a", encoding="utf-8")
Créer uniquement si nouveauopen("f.txt", "x", encoding="utf-8")
Écrire des données binairesopen("f.bin", "wb")
Écrire une seule chaînef.write("text\n")
Écrire une liste de chaînesf.writelines(lines)
Écriture texte en une foisPath("f.txt").write_text("...", encoding="utf-8")
Écriture binaire en une foisPath("f.bin").write_bytes(b"...")
Écriture sûre / atomiqueÉcrire dans un fichier temporaire, puis os.replace()

Chapitres connexes

Was this page helpful?