Aller au contenu

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! 🍪 🍰 🍇 ) :

Fichier : fruits.txt

scones
myrtilles
fraises
framboises
oranges

Extension
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'ouvrir, en mode lecture seule, grâce à la commande:

>>> 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 un handle :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édente
  • r désigne le mode d'ouverture du fichier choisi : Ici, r (=read) signifie que le fichier est ouvert en mode lecture 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() En effet, Il existe une autre méthode, de même nom, mais SANS le s 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"]

Exemple

>>> 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() ou faire_autrechose() plantent, càd lèvent une exception, alors la ligne monFichier.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é with est ce que l'on appelle un gestionnaire de contexte, il est utilisé pour :

  • 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é avec with, le mot-clé as permet de définir une variable de manipulation des ressources 🇫🇷, ou handle :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
  • 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 bloc with ) : En cas de problème/exception rencontrée durant l'ouverture du fichier, c'est le gestionnaire de contexte with qui garantit la bonne fermeture du fichier
  • À l'intérieur du contexte (à l'intérieur du bloc with ), 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 contexte with qui garantit la bonne fermeture du fichier
  • À la sortie du contexte (en sortant du bloc with ) : C'est le gestionnaire de contexte with qui fermera automatiquement le fichier. On n'a donc plus besoin d’utiliser la méthode close().
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 fichier
  • a : pour ajouter/écriture seulement en fin de fichier

Lettre Signification Mode d'Ouverture
r read Mode Lecture Seule
Mode Par défaut
Contenus renvoyés sous forme de str :
Les Octets (Bytes) sont préalablement
décodés
en utilisant :
  • un encodage par défaut,
    dépendant de la plateforme, ou bien
  • l'encodage passé en argument dans
    le paramètre encoding=..., s'il a été précisé
w write Mode Écriture
⚠ Écrase le contenu courant ⚠
Crée le fichier s'il n'existe pas
a append Mode Ajout en Fin de Fichier

Écriture dans un fichier

Écriture Simple

with open("fruits.txt", "w") as monFichier:
    monFichier.write("Bonjour\n")
    monFichier.write("Maman")

Écriture Avec Variables

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 et
  • b pour les fichiers Binaires (Images, Sons, Vidéos, etc...)

Lettre Signification Mode d'Ouverture
x eXclusive Mode Lecture Seule, avec création Exclusive :
renvoie une erreur si le fichier existe déjà
b Binaire 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 Texte Mode Texte
Mode par défaut : r = rt
Contenus renvoyés sous forme de str
Octets décodés avec un encodage (idem que r )
+ Lecture + Écriture Mode Modification
Lecture et Écriture

  • r est équivalent à rt
  • r+ / r+b: ouvre un fichier texte/binaire SANS troncature
  • w+ / w+b: ouvre un fichier texte/binaire AVEC troncature

cf la Page correspondante de la Documentation Officielle