Files
training.python.beginner/documentation/08-text-files.md
Steve Kossouho 77aa231f5b Update first chapters and new questions
Updated first chapter slides.
Added new questions in the new training section.
2025-07-07 21:18:04 +02:00

14 KiB
Raw Blame History

title, author
title author
Manipuler des fichiers texte Steve Kossouho

Découvrir comment manipuler des fichiers texte


Écrire et lire des fichiers (version de base)

Python vous offre, sans import nécessaire, une fonction open{.python} vous permettant d'ouvrir des fichiers pour les manipuler. Cette fonction semble provenir du module io{.python} de la bibliothèque standard.

Pour ouvrir un fichier en écriture :

file = open("fichier.txt", "w", encoding="utf-8")  # Ouvrir le fichier
file.write("Texte à écrire\nDeuxième ligne.\n")
file.write("Troisième ligne.")
file.close()  # Toujours penser à le refermer, pour votre système

La fonction open(){.python} prend quelques arguments importants :

  • filename : chemin de fichier relatif (au répertoire de travail) ou absolu
  • mode : "w" pour write, "r" pour read, "a" pour append
  • encoding: rendez-le explicite, et "utf-8" si possible

Pages de code les plus fréquemment rencontrées :

  1. utf-8 : ±90% du temps (complètement rétrocompatible avec ASCII)
  2. windows-1252 ou 1252 : ±5% du temps (provient de Windows 95)
  3. latin-1 : ±5% du temps (aussi nommé iso8859-1)
  4. utf-16 : certains pays n'utilisant quasiment pas de caractères ASCII, ils produisent souvent de l'UTF-16 (ex. Chine, Russie)

Plus : Échappement de caractères

  • Échappements classiques 0 à 8 bits (0 à 255)
  • Échappements de caractères 0 à 16 bits (256 à 65535)
  • Échappements de caractères 0 à 32 bits (65536 et plus)
print("\x41 = \101 = A")  # codes 8 bits, 2 caractères obligatoires
print("\u00E6 = æ")  # codes 16 bits, 4 caractères obligatoires
print("\U0001F44D = 👍️")  # codes 32 bits, 8 caractères obligatoires

Algorithme UTF-8


Ouvrir un fichier en lecture

file = open("fichier.txt", "r", encoding="utf-8")
line1 = file.readline()  # Lit une ligne, et avance le curseur à la ligne suivante
rest1 = file.read()  # Lit le fichier jusqu'à la fin
file.close()  # Toujours penser à le refermer, pour votre système

Outils disponibles pour gérer des fichiers

Si l'on utilise des éditeurs de texte, on pourrait penser qu'il est facile de demander à Python de, par exemple :

- Remplacer une ligne
- Lire une ligne arbitraire d'un document
- Supprimer une ligne
- Remplacer du texte

Aucune de ces fonctionnalités n'existe en standard, dans aucun langage; les logiciels qui vous permettent ces manipulations sont obligés, souvent, de conserver une copie du document en mémoire (quand c'est possible) et d'effectuer les manipulations en mémoire avant de réécrire tout ou partie du fichier.

Tout ce qu'on a d'utile, c'est :

- Ajouter du contenu à la fin
- Réécrire le fichier
- Lire ligne par ligne du début, jusqu'à arriver à une ligne arbitraire
- Déplacer le curseur à une position en octets

Une bibliothèque externe Python propose des outils pour effectuer certaines de ces actions :

pip install textfile

Page PyPI du package textfile


Écrire et lire des fichiers (gestionnaire de contexte)

Une version raccourcie du f = open(){.python} … f.close(){.python} consiste à utiliser un gestionnaire de contexte (la formation Python intermédiaire explique le concept). La syntaxe consiste en ce qui suit :

with open("fichier.txt", "r", encoding="utf-8") as file:
    # `file.close()` : appelé automatiquement en fin de bloc
    text = file.read()

À la fin de l'exécution du bloc, une méthode spéciale est automatiquement appelée et ferme le descripteur de fichier s'il est resté ouvert. Plus besoin d'exécuter manuellement file.close(){.python}


Bonus: Ouverture simultanée de fichiers

Avec un seul bloc withas, il est possible d'utiliser plusieurs gestionnaires de contexte en même temps, par exemple, si l'on veut ouvrir un fichier en lecture, faire une conversion de données et les écrire dans un fichier ouvert en écriture, on peut :

with open("input.txt", "r") as infile, open("output.txt", "w") as outfile:
    data = infile.read().upper()  # tout mettre en majuscules
    outfile.write(data)

Parcourir facilement les lignes d'un fichier

Il est possible, lorsque vous avez un descripteur de fichier ouvert, de parcourir facilement ligne à ligne le contenu de votre fichier texte, en utilisant le mot-clé for{.python} :

with open("fichier.ext", "r", encoding="utf-8") as file:
    for line in file:
        print(line)

En interne, ici la fonction open(){.python} est exécutée en deux temps; un première fois pour renvoyer le descripteur de fichier, et une seconde fois lors de la fin du bloc... Mais c'est un peu magique, et c'est un sujet pour une formation plus avancée de Python.


Formats structurés : JSON

Le JSON (JavaScript Object Notation) est un format de texte extrêmement populaire pour partager des données hiérarchiques. Il a largement supplanté le XML dans les systèmes modernes et les services web. Les données contenues dans un fichier texte au format JSON peuvent être interprétées et transformées en données Python, telles que dictionnaires et listes, nombres etc.


Lecture et écriture de fichiers JSON

Il est extrêmement facile de lire ou d'écrire du contenu depuis ou vers un fichier représentant une structure JSON. Documentation du module JSON

import json

# Lire un fichier JSON
with open("fichier.json", "r", encoding="utf-8") as file:
    data = json.load(file)

# Écrire un fichier JSON, l'objet à écrire doit être une liste ou
# un dictionnaire
with open("copie.json", "w", encoding="utf-8") as file:
    json.dump(data, file, indent=2)

Formats structurés : CSV

Le CSV est un format accessible et non propriétaire pour représenter des données tabulées (en table) . C'est un format texte, utilisant, par défaut, des virgules et des retours à la ligne pour séparer les lignes et colonnes.

La manipulation des CSV fait aussi partie de la bibliothèque standard de Python. Documentation CSV


Parcourir les lignes d'un fichier CSV

Lire le contenu d'un fichier CSV est presque aussi simple que pour un fichier JSON, à quelques détails près :

import csv

with open("fichier.csv", "r", encoding="utf-8") as file:
    reader = csv.reader(file, delimiter=",")
    for row in reader:
        print(row)  # Affiche une ligne sous forme d'une liste de chaînes de caractères

Vous ouvrez d'abord votre fichier en lecture et en mode texte, comme tout fichier texte, puis vous créez un objet de type lecteur, configuré pour lire et interpréter le contenu de lignes du document. Par défaut, le lecteur ne reconnaît que les documents dont les cellules sont séparées par la virgule , et dont les lignes sont séparées par \n. Heureusement, cet objet peut être configuré pour comprendre des fichiers avec des propriétés différentes.


Paramètres de formatage d'un fichier CSV

Pour lire ou écrire un fichier CSV, il est possible de configurer les objets en charge d'interpréter ou de formater le contenu du fichier. En lecture, vous configurerez un objet de type reader, et en écriture... writer. Dans les deux cas, la procédure sera la même.

Vous avez trois façons de configurer votre objet lecteur ou écrivain :

  • Soit en passant un objet de type Dialect, un objet dont les attributs servent à configurer toutes les facettes du formatage d'un fichier CSV;
  • soit en passant un nom d'objet de type Dialect, par exemple "excel" (séparateur virgule);
  • soit en passant des arguments individuels qui correspondent aux attributs des objets Dialect.

Configuration via un objet Dialect

Pour définir votre propre Dialect, vous pouvez créer une classe héritant de Dialect, dans laquelle vous n'avez qu'à redéfinir les attributs dont vous souhaitez changer la valeur. Voir Classe Dialect du module CSV pour connaître les valeurs de base.

import csv

class MonDialecte(csv.Dialect):
    """Dialecte CSV utilisant des // comme séparateur."""
    delimiter = "//"

Une fois que votre dialecte est défini et prêt à l'usage, vous pouvez l'utiliser pour lire ou écrire un fichier :

import csv

class MonDialecte(csv.Dialect):
    """Dialecte CSV utilisant des // comme séparateur."""
    delimiter = "//"

with open("fichier.csv", "r", encoding="utf-8") as file:
    reader = csv.reader(file, dialect=MonDialecte())
    for row in reader:
        print(row)

Plutôt que de créer une classe de dialecte pour personnaliser la manipulation d'un fichier, il est possible de passer à l'argument dialect une chaîne de caractères représentant le nom d'un dialecte prédéfini. Par défaut, les valeurs disponibles sont "excel", "excel-tab" et "unix".

...
reader = csv.reader(file, dialect="excel")

Vous pouvez aussi enregistrer des noms de dialecte supplémentaires en utilisant la fonction csv.register_dialect(name, dialect).

import csv

class MonDialecte(csv.Dialect):
    """Dialecte CSV utilisant des // comme séparateur."""
    delimiter = "//"
    
csv.register_dialect("mondialecte", MonDialecte)

Configuration via les attributs de Dialect

Pour gagner du temps, il est possible, lorsque vous créez votre objet lecteur ou écrivain, de passer des arguments pour préciser le format du fichier CSV à lire ou à écrire. Ces arguments ont les mêmes noms que les attributs de la classe Dialect, et ont le même usage.

import csv

with open("fichier.csv", "r", encoding="utf-8") as file:
    reader = csv.reader(file, delimiter=";", doublequotechar=True)  # etc., etc.
    for row in reader:
        print(row)

Détecter le dialecte d'un fichier

Outre la configuration de dialecte manuelle, il est possible de demander à Python d'autodétecter les propriétés de formatage d'un fichier CSV, et de générer automatiquement un objet Dialect. Pour cela, vous devez utiliser la classe csv.Sniffer :

import csv

with open("output.csv", "r", encoding="utf-8") as file:
    dialect = csv.Sniffer().sniff(file.read())  # Lire le contenu du fichier pour détecter le dialecte
    file.seek(0)  # Revenir au début du fichier pour démarrer la lecture
    reader = csv.reader(file, dialect=dialect)
    for row in reader:
        print(row)

Exemple: Copier un fichier CSV vers un fichier cible

On peut avec le module CSV lire un contenu CSV dans un objet Python, puis réécrire le contenu de cet objet dans un nouveau fichier CSV.

import csv

table = list()  # Objet à utiliser pour stocker le contenu
with open("fichier.csv", "r", encoding="utf-8") as file:
    reader = csv.reader(file, delimiter=",")
    for row in reader:
        table.append(row)  # Ajouter la ligne comme élément de `table`

with open("copie.csv", "w", encoding="utf-8") as file:
    writer = csv.writer(file, delimiter=";")
    writer.writerows(table)  # table doit être une liste de listes

Lire chaque ligne sous forme de dictionnaire

Si votre fichier CSV contient des en-têtes, et que vous préférez les utiliser pour retrouver le contenu d'une colonne, plutôt qu'utiliser son indice, vous pouvez procéder à l'utilisation d'un DictReader :

import csv

with open("example-file.csv", "r", encoding="utf-8") as csvfile:
    reader = csv.DictReader(csvfile)  # lit automatiquement l'en-tête pour définir les clés des dictionnaires
    for row in reader:  # lit les lignes suivantes, renvoyées sous forme de dictionnaires
        print(row)
        print(row["<texte de la colonne d'en-tête>"])

Lire un CSV sans en-tête via dictionnaires

Si votre fichier CSV ne contient pas de ligne d'en-tête, mais que vous souhaitez quand même définir des en-têtes à associer aux colonnes, vous pouvez utiliser un DictReader et préciser un argument fieldnames= :

import csv

with open("example-file.csv", "r", encoding="utf-8") as csvfile:
    reader = csv.DictReader(csvfile, fieldnames=["col1", "col2"])  # définit les en-têtes
    for row in reader:  # lit les lignes suivantes, renvoyées sous forme de dictionnaires
        print(row)  # renvoie un dictionnaire avec des clés "col1" et "col2"
        print(row["col1"])

Écrire un fichier CSV

import csv

# Créer une liste de listes pour imiter une feuille de calcul
rows = []
for i in range(10):
    rows.append([str(j + i) for j in range(10)])


# Sous Windows, il faut préciser un argument newline à la fonction open, sinon
# chaque ajout de ligne causera deux passages à la ligne
with open("output.csv", "w", encoding="utf-8", newline="") as file:
    writer = csv.writer(file, delimiter=";")
    writer.writerows(rows)


Écrire un CSV avec des en-têtes

headers = ["nom", "prenom"]
content = [
    {"nom": "Doe", "prenom": "John"},
    {"nom": "Smith", "prenom": "Jane"}
]

with open("header-output.csv", "w", encoding="utf-8") as file:
    # Initialiser le writer en précisant la liste des textes d"'en-tête
    writer = csv.DictWriter(file, fieldnames=headers)
    # Écrire la ligne d'en-tête
    writer.writeheader()
    # Écrire le contenu restant
    writer.writerows(content)

Exemple avec un DictWriter