Aller au contenu principal

Lecture et écriture de fichiers

Les E/S de fichiers franchissent une frontière entre l'état du programme et un système de fichiers externe. Rendez explicites le format, l'encodage, le mode et le comportement en cas d'échec.

Durée de vie des ressources

Utilisez un gestionnaire de contexte afin que le fichier soit fermé même lorsqu'une exception survient :

from pathlib import Path

path = Path("notes.txt")
with path.open("r", encoding="utf-8") as handle:
for line in handle:
process(line.rstrip("\n"))

L'itération sur le fichier diffuse les lignes. read() et readlines() chargent le contenu restant en mémoire et doivent être réservés aux entrées bornées. rstrip("\n") retire la fin de ligne sans supprimer les espaces significatifs comme le ferait un strip() sans argument.

Modes texte et binaire

Le mode texte décode les octets en str ; le mode binaire renvoie des bytes inchangés.

text = path.read_text(encoding="utf-8")
payload = Path("image.bin").read_bytes()

Précisez l'encodage d'un texte durable plutôt que de dépendre des paramètres régionaux de la machine. La conversion des fins de ligne appartient aussi au mode texte ; passez newline= lorsqu'un format exige un contrôle précis.

Les principaux modes sont :

ModeSignificationFichier existant
rlecturerequis
wécrituretronqué
aajoutconservé
xcréation exclusivene doit pas exister

Ajoutez b pour le mode binaire ou + pour combiner lecture et écriture. Considérez w comme une opération destructive.

Formats structurés

Utilisez une bibliothèque qui connaît le format plutôt qu'un découpage manuel de chaînes :

import json

with Path("settings.json").open("r", encoding="utf-8") as handle:
settings = json.load(handle)

Employez csv pour les données délimitées et ouvrez les fichiers CSV avec newline="" comme le recommande sa documentation. L'analyse syntaxique ne valide pas le sens métier ; vérifiez séparément le schéma, les plages et les champs obligatoires.

Échecs et remplacement plus sûr

Ne traitez que les erreurs pour lesquelles le programme possède une stratégie de récupération, telles que FileNotFoundError, PermissionError, les erreurs de décodage ou les données de format invalides. Ne réduisez pas tous les échecs à un résultat vide.

Pour une sortie importante, écrivez un fichier temporaire dans le même répertoire, videz les tampons et fermez-le, puis remplacez la destination. Un renommage dans le même système de fichiers peut éviter aux lecteurs d'observer un fichier partiellement écrit, mais la durabilité après un arrêt brutal peut aussi exiger une synchronisation propre au système. Le remplacement atomique ne coordonne pas plusieurs auteurs concurrents.

Écrire puis relire sans fichier préexistant

Cet exemple utilise un répertoire temporaire isolé, nettoyé à la sortie. Les méthodes des fichiers agissent depuis la position courante du flux, pas depuis le début à chaque appel.

from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as directory:
path = Path(directory) / "notes.txt"
with path.open("x", encoding="utf-8", newline="\n") as handle:
assert handle.write("café\n\n") == 6
with path.open("r", encoding="utf-8") as handle:
assert handle.readline() == "café\n"
assert handle.readline() == "\n" # ligne vide, pas fin de fichier
assert handle.readline() == "" # fin de fichier
handle.seek(0)
assert handle.read() == "café\n\n"
assert handle.closed

write n'ajoute pas automatiquement de fin de ligne et renvoie le nombre de caractères écrits, pas d'octets encodés. En texte, read(size) compte les caractères ; en binaire, les octets. En texte, tell() renvoie un marqueur de position opaque, pas un indice de caractère général. Utilisez seek(0) pour recommencer ou une valeur sauvegardée de tell(), plutôt que des décalages arbitraires en octets.

Avec newline=None par défaut, la lecture traduit \r, \r\n et \n en \n ; une ligne vide reste donc distincte de la fin du fichier. a crée un fichier absent ou ajoute au fichier existant ; r+ exige un fichier existant sans le tronquer, tandis que w+ le tronque à l'ouverture. Aucun ne crée les répertoires parents manquants. Fermer un fichier vide les tampons Python, sans garantir à lui seul la persistance après une coupure de courant.

Sources

Explorer les liensOuvrir le réseau