14 KiB
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 absolumode
:"w"
pour write,"r"
pour read,"a"
pour appendencoding
: rendez-le explicite, et "utf-8" si possible
Pages de code les plus fréquemment rencontrées :
utf-8
: ±90% du temps (complètement rétrocompatible avecASCII
)windows-1252
ou1252
: ±5% du temps (provient de Windows 95)latin-1
: ±5% du temps (aussi nomméiso8859-1
)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
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
É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 with
… as
, 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