1NSI : cours Fichiers⚓︎
Introduction⚓︎
Le but de ce TD est d'apprendre à créer, à lire et à écrire dans des fichiers Texte en Python
Pour commencer : Créer un fichier texte⚓︎
Créer et renseigner, avec votre IDE favori (VScode?), un fichier texte nommé fruits.txt
contenant par exemple les informations suivantes (adapter selon vos goûts! ) :
scones
myrtilles
fraises
framboises
oranges
L'extension choisie .txt
est une des possibilités, mais on aurait pu choisir toute autre extension de fichier texte, comme par exemple l'extension .md
pour le markdown, etc...
Ouverture / Lecture / Fermeture d'un Fichier Texte⚓︎
Ouverture d'un fichier en Lecture Seule, avec open(nomFichier, 'r')
⚓︎
Ce paragraphe détaille l'ouverture en mode lecture seule d'un fichier.
Fichier Texte situé dans le même répertoire que le script Python⚓︎
On suppose ici que le fichier texte se trouve dans le même répertoire que le script/fichier Python (en .py
) qui doit l'ouvrir.
Pour lire un fichier texte, depuis Python, il faut commencer par l'
>>> monFichier = open("fruits.txt", "r")
>>> monFichier = open("fruits.txt", "r", encoding='utf-8')
monFichier
est le nom (personnalisable) d'une variable de manipulation de fichier (dans Python) ou unhandle :uk:, c'est-à-dire une variable qui sert à manipuler le fichier, une fois ouvert."fruits.txt"
est la chaîne de caractère du nom du fichier texte qui doit se trouver dans le même répertoire que le fichier python en.py
contenant l'instruction précédenter
désigne le mode d'ouverture du fichier choisi : Ici,r
(=read) signifie que le fichier est ouvert en modelecture seule
:- le fichier est ouvert, mais n'est pas encore lu. Comme on ouvre un livre, sans l'avoir encore lu.
- un
curseur
est placé en première position de sorte à pouvoir lire le premier caractère. Comme on ouvre un libre à la première page, première ligne, premier caractère. Sans l'avoir lu.
encoding='utf-8'
est un paramètre OPTIONNEL qui précise l'encodage. Cf. la Liste des encodages acceptés par Python, sur la Documentation Officielle (ainsi que leurs alias...)
L'affichage du contenu de la variable monFichier
, dans un interpréteur Python, prouve que le contenu de monFichier
est vu comme un objet de type fichier ouvert :
>>> monFichier
<_io.TextIOWrapper name='fruits.txt' mode='r' encoding='UTF-8'>
Fichier Texte situé dans un AUTRE répertoire que le script Python⚓︎
On suppose ici que le fichier texte se trouve dans un autre répertoire que le script/fichier Python (en .py
) qui doit l'ouvrir, en mode lecture seule.
# Dans un sous-dossier du répertoire courant "."
open("./dossier1/dossier2/fruits.txt", "r")
# Dans un dossier parent, plus proche de la racine :
# ".." représente le répertoire parent du répertoire courant
open("../fruits.txt", "r")
Lecture Complète avec la Méthode readlines()
⚓︎
Notez le s
dans readlines
Par souci de simplicité, dans toute la suite, nous supposerons que le fichier fruits.txt
se trouve dans le même répertoire que votre script Python.
Définition de readlines()
⚓︎
La méthode readlines()
:
- lit toutes les lignes du fichier Texte en un seul coup. Comme on lirait toutes les lignes du livre en un seul coup.
-
renvoie une liste dans laquelle :
- chaque élément de la liste contient une ligne du fichier texte finissant par
\n
(line feed = retour à la ligne), - sauf le dernier, qui contient la dernière ligne, mais pas de dernier
\n
final:
["ligne1\n", "ligne2\n", .., "ligneAvantDerniere\n", "ligneDerniere"]
- chaque élément de la liste contient une ligne du fichier texte finissant par
>>> monFichier.readlines()
['scones\n', 'myrtilles\n', 'fraises\n', 'framboises\n', 'oranges\n']
Parcourir chaque ligne du fichier, une par une, avec readlines()
⚓︎
monFichier = open("fruits.txt", "r")
lignes = monFichier.readlines()
for ligne in lignes:
print(ligne)
Fermeture du fichier⚓︎
Il est important que tout fichier ouvert, soit ultimement fermé, une fois que les opérations sur ce dernier sont finies, sinon on risque de rencontrer une erreur lors de la poursuite du script.
La méthode close()
ferme le fichier. Comme on fermerait un livre (quelle que soit la page courante).
Tout fichier fermé n'est plus manipulable :
>>> monFichier.close()
# Après fermeture du fichier, on ne peut plus le lire...
>>> monFichier.readlines()
ValueError: I/O operation on closed file.
Instruction with
.. as
..⚓︎
Limites de la Syntaxe précédente⚓︎
Le résumé de ce qui précède est que l'on peut manipuler un fichier avec, par exemple, les instructions suivantes :
monFichier = open("fruits.txt","r")
faire_quelquechose()
monFichier.readlines()
faire_autrechose()
monFichier.close()
Cette syntaxe peut néanmoins poser plusieurs problèmes :
- Une certaine répétition dans le processus de manipulation des fichiers:
- ouverture
- fermeture
- L'oubli de fermeture du fichier avec
close()
, peut provoquer la levée d'une exception/erreur durant l'exécution du code. - Si les autres opérations
faire_quelquechose()
oufaire_autrechose()
plantent, càd lèvent une exception, alors la lignemonFichier.close()
n'est jamais atteinte donc jamais exécutée. Le fichier ne sera donc pas fermé, ce qui peut encore poser des problèmes.
On pourra noter qu'il existe en Python des outils pour gérer les exceptions, notamment try
, except
, finally
, etc.. mais ces outils ont des syntaxes assez verbeuses, càd inutilement longues et fastidieuses à rédiger. Or la manipulation de fichiers est assez commune, on souhaiterait donc quelque chose de simple.
Généralisation à d'autres Contextes⚓︎
Plus généralement, dans certains autres contextes de programmation , on rencontre les mêmes problèmes que la manipulation de fichiers, par exemple:
- ouverture / fermeture :
- de fichiers,
- de sockets, etc...
- verrouillage / déverrouillage :
- d'une ressource critique,
- d'un verrou / threading.Lock, etc..
- modifier / réinitialiser :
- une transaction d'une base de donnée (opérations bancaires, etc..),
- des ressources temporaires par exemple :
- pour l'écriture de tests,
- pour modifier temporairement l'environnement courant : répertoire de travail, redirection d'entrées - sorties, etc..
- démarrer / arrêter :
- un chronomètre
- une tâche de fond/un démon, etc...
Pour tous ces exemples, on retrouve donc les mêmes problématiques :
- de répétition d'instructions : AVANT / APRÈS
- de gestion des exceptions (erreurs) assez verbeuses
Comme on peut le voir, il s'agit d'un problème assez fréquent, et on aimerait donc le résoudre simplement :
Une Solution : le gestionnaire de contexte with
⚓︎
Pour résoudre les problèmes détaillés précédemment, on utilise ce que l'on appelle un gestionnaire de contexte :
Gestionnaire de Contexte
En Python, le mot-clé
- exécuter automatiquement des opérations :
- en entrée du
contexte (càd en entrant dans le blocwith
) : mise à disposition des ressources. En outre, associé avecwith
, le mot-cléas permet de définir une variable de manipulation des ressources , ouhandle :uk: Remarque : Le mot-cléas
est facultatif de manière générale, mais est toujours utilisé lorsque les ressources manipulées sont des fichiers. - en sortie du contexte (en sortant du bloc
with
) : libération automatique des ressources
- en entrée du
- définir une portée particulière : entre l'entrée et la sortie du contexte
manipulation de fichiers avec with
À l'entrée du contexte (en entrant dans le blocwith
) : En cas de problème/exception rencontrée durant l'ouverture du fichier, c'est le gestionnaire de contextewith
qui garantit la bonne fermeture du fichierÀ l'intérieur du contexte (à l'intérieur du blocwith
), c'est là qu'on effectue toutes les opérations sur le fichier : En cas de problème/exception rencontrée lors de la lecture/écriture du fichier, c'est le le gestionnaire de contextewith
qui garantit la bonne fermeture du fichierÀ la sortie du contexte (en sortant du blocwith
) : C'est le gestionnaire de contextewith
qui fermera automatiquement le fichier. On n'a donc plus besoin d’utiliser la méthodeclose()
.
with open("fruits.txt", "r") as monFichier:
lignes = monFichier.readlines()
for ligne in lignes:
print(ligne)
Cette syntaxe est donc plus concise, évite les redites, et est plus sécurisée, et sera généralisable à d'autres situations : elle sera donc privilégiée dans toute la suite.
Autres Méthodes de Lecture Seules d'un Fichier⚓︎
La Méthode read()
⚓︎
La Méthode read()
La méthode read()
lit et renvoie tout le contenu du fichier sous forme d'une unique chaîne de caractère : "ligne1\nligne2\n ... \nligne_derniere\n"
with open("fruits.txt", "r") as monFichier:
maChaine = monFichier.read()
print(maChaine)
La Méthode readline()
⚓︎
Notez bien l'absence de s
, à la fin de readline()
: cette méthode est distincte de la méthode readlineS() étudiée précédemment.
La Méthode readline()
La méthode readline()
lit et renvoie une seule ligne d'un fichier sous forme de chaîne de caractères. Chaque nouvel appel de readline()
, renvoie la ligne suivante.
Parcours de fichier avec with
et while
⚓︎
with open("fruits.txt", "r") as monFichier:
ligne = monFichier.readline()
while ligne != "":
print(ligne)
ligne = monFichier.readline()
Parcours de fichier avec with
et for
⚓︎
with open("fruits.txt", "r") as monFichier:
for ligne in monFichier:
print(ligne)
Chaque ligne est une chaîne de caractère str
Autres Modes d'Ouverture de Fichiers⚓︎
Principaux Modes d'Ouvertures⚓︎
On souhaite aussi usuellement, pouvoir écrire dans un fichier, pour cela deux modes existent:
w
: En commençant par écraser totalement l'éventuel contenu courant du fichiera
: pour ajouter/écriture seulement en fin de fichier
Lettre | Signification | Mode d'Ouverture |
---|---|---|
r |
Mode Lecture Seule Contenus renvoyés sous forme de str :Les Octets (Bytes) sont préalablement décodés en utilisant :
|
|
w |
Mode Écriture Écrase le contenu courant Crée le fichier s'il n'existe pas |
|
a |
Mode Ajout en Fin de Fichier |
Écriture dans un fichier
with open("fruits.txt", "w") as monFichier:
monFichier.write("Bonjour\n")
monFichier.write("Maman")
unFruit = "Melon"
unAutre = "Mandarine"
with open("fruits.txt", "w") as monFichier:
monFichier.write(unFruit+"\n")
# monFichier.write(f"{unFruit}\n")
monFichier.write(unAutre)
mesAliments = ["scones","crêpes","myrtilles","mangues","tapioca"]
with open("fruits.txt", "w") as monFichier:
for aliment in mesAliments:
monFichier.write(f"{aliment}\n")
Autres Modes d'Ouvertures⚓︎
Python fait la distinction entre :
t
(la valeur par défaut) pour les fichiers Texte etb
pour les fichiers Binaires (Images, Sons, Vidéos, etc...)
Lettre | Signification | Mode d'Ouverture |
---|---|---|
x |
e |
Mode Lecture Seule, avec création Exclusive : renvoie une erreur si le fichier existe déjà |
b |
Mode Binaire Fichiers Images, Audios, Vidéos, etc.. Les contenus sont renvoyés sous forme d'objets qui sont des Octets (**B**ytes) sans aucun décodage |
|
t |
Mode Texter = rt Contenus renvoyés sous forme de str Octets décodés avec un encodage (idem que r ) |
|
+ |
Lecture |
Mode Modification Lecture et Écriture |
r
est équivalent àrt
r+
/r+b
: ouvre un fichiertexte
/binaire
SANS troncaturew+
/w+b
: ouvre un fichiertexte
/binaire
AVEC troncature
cf la Page correspondante de la Documentation Officielle