Accueil

Tutoriel Python - sommaire

Les fichiers de données en Python

En mode commande ou en mode programmé, on peut manipuler des fichiers de données (extension .txt).
Mais pourquoi utiliser des fichiers de données dans le cadre de programmes Python ?
Dès que vous fermez un programme les données contenues dans les variables ne sont pas sauvegardées.
Imaginez un jeu, il faut sauvegarder les scores.
Imaginez un programme nécessitant beaucoup de données, il ne serait pas judicieux de stocker celles-ci dans des listes ou tuples ou dictionnaires ou 'set' du programme.
Dans ces deux cas il est préférable d'écrire / lire dans des fichiers de données.
Le plus souvent on dit tout simplement "fichiers" pour désigner les fichiers de données.

Contenu provisoire du fichier "taxons.txt" :

Éponges
Cnidaires
Cténaires
Vers
Crustacés
Échinodernes
Bryozaires
Urocordés
Poissons osseux
Poissons cartilagineux
Gastéropodes
Bivalves
Céphalopodes
Cirripèdes
Décapodes

Contenu provisoire du fichier de données "especes.txt" :

Seiche
Calmar
Pouple
Moule commune
Huitre creuse
Huitre plate
Balane
Crevette grise
Bouquet
Sole
Bar
Crabe vert
Étrille
Tourteau
Arénicole

Remarque : dans les deux fichiers, une donnée par ligne.

Manipuler les fichiers de données avec l'interpréteur

Première batterie de commandes

>>> import os
>>> os.getcwd()
'C:\\Python39'

Dès que vous êtes sous l'interpréteur le répertoire par défaut est celui qui contient l'exécutable de l'interpréteur.
La commande os.getcwd() précise le répertoire courant.
Or mes programmes (fichiers d'extension .py) et mes fichiers de données (fichiers d'extension .txt) sont dans le dossier c:\\python_prog.
Il faut donc changer de "directory" . Les fonctions qui permettent d'afficher le dossier courant, de changer de répertoire courant, etc. sont dans le module os.

>>> os.chdir("c:/python_prog")
>>> fichier = open("especes.txt", "r")
>>> fichier.readlines()
['seiche\n', 'calmar\n', 'pouple\n', 'moule commune\n', 'huitre creuse\n', 'huitre plate\n', 'balane\n',
 'crevette grise\n', 'bouquet\n', '\n']
>>>fichier.close()
>>> fichier = open("taxons.txt","r")
>>> fichier.readlines()
['éponges\n', 'cnidaires\n', 'cténaires\n', 'vers\n', 'mollusques\n', 'crustacés\n', 'échinodernes\n', 
'bryozaires\n', 'urocordés\n', 'poissons osseux\n', 'poissons cartilagineux\n']
>>>fichier.close()
>>> fichier =open('especes.txt','r')
>>> print(fichier.readline())
seiche
>>> print(fichier.readline())
calmar
>>>fichier.close()

os.chdir("c:/python_prog") : accès au répertoire qui contient mes fichiers .txt
Pour lire le contenu d'un fichier il faut l'ouvrir en lecture seule.
Donc dans la fonction open() le deuxième argument doit être "r" (comme 'read').
La méthode readlines() (avec un 's') appliquée à l'objet 'file' permet de lire tout le fichier et retourne son contenu sous forme d'une liste.
Notez que chaque élément de la liste se termine par '\n' (symbole qui commande un saut de ligne).

la méthode readline() (sans 's') permet de lire la ligne courante. Après l'ouverture d'un fichier, la ligne courante est la première.
La méthode provoque aussi le déplacement du pointeur vers la ligne suivante ou EOF (End Of File).

Deuxième batterie de commandes

>>> import os
>>> os.getcwd()
'C:\\Python39'
>>> os.chdir("c:/python_prog")
>>> fichier = open("especes.txt","a")
>>> fichier.write("\n sole")
>>> fichier.write("\n bar")
>>> fichier.readlines()
...
io.UnsupportedOperation: not readable
>>> fichier.close()

Pour pouvoir ajouter du contenu à un fichier il faut l'ouvrir en mode ajout (deuxième argument :"a").
Pour ajouter une ligne, il faut utiliser la méthode write() à l'objet de type 'file'.
La chaine ajoutée, doit contenir "\n" pour créer un saut de ligne.

On ne peut pas lire un fichier ouvert en ajout. Vous voyez ci-dessus que j'ai tenté de le faire et j'ai eu un message d'erreur.
N'oubliez pas de fermer le fichier avec la méthode close().

Manipuler les fichiers de données dans le cadre de programmes

Un conseil : le programme (fichier d'extension .py) et le fichier de données traité par ce programme, doivent être dans le même répertoire.
Ainsi le problème parfois délicat du chemin relatif sera résolu ...

Programme pour lire séquentiellement un des deux fichiers

Le programme ci-dessous ouvre en lecture "especes.txt" OU "taxons.txt".

#nom programme : ouvrir_en_lecture.py
#objet : ouvrir le fichier de données 'especes' ou 'taxons' en lecture

nom_fichier =input("tapez 'especes.txt' ou 'taxons.txt' : ")

with open(nom_fichier, "r") as fichier: 
    ligne = fichier.readline()      # lire première ligne du fichier
    while ligne != "":
        print(ligne)
        ligne = fichier.readline() #lire ligne suivante
fichier.close()

Notez la syntaxe pour ouvrir le fichier : with open(nom_fichier, "r") as fichier
Cette instruction permet d'ouvrir et de fermer un fichier de manière efficace. Si pour une raison ou une autre, l'ouverture ou la lecture du fichier conduit à une erreur, l'utilisation de la structure "width … open … as … garantit une fermeture effective du fichier.

La méthode realine() appliquée à l'objet 'file' permet de lire une ligne dans le fichier.
readline() veut dire "lire la ligne pointée". Après ouverture d'un fichier, la ligne "pointée" est la première.

La commande de fermeture doit être au niveau d'indentation que la commande d'ouverture.
Trace de l'exécution (extrait) :

 
Tapez 'especes.txt' ou 'taxons.txt' : especes.txt
seiche
calmar
pouple
moule commune
huitre creuse
huitre plate
balane
crevette grise

Programme pour ajouter des données à l'un des deux fichiers

Le programme ci-dessous permet d'ajouter des lignes à "especes.txt" OU "taxons.txt".

#nom programme : ouvrir_en_ajout.py
# objet : ouvrir en ajout especes.txt ou taxons.txt

nom_fichier = input("tapez 'especes.txt' ou 'taxons.txt' : " )
reponse ="o"
with open(nom_fichier, "a") as fichier:
    while reponse  in "oO":
        ajout =input ("saisir une espèce ou un taxon : ")
        ajout = "\n" + ajout
        fichier.write(ajout)
        reponse =input( "Encore des ajouts O/N ? : " )
fichier.close()

Pour ajouter des données, en fin de fichier, il faut l'ouvrir en mode "a" (comme "append").
Pour créer une nouvelle ligne dans le fichier de données il faut utiliser la méthode write() à l'objet de type 'file'.

Programme pour faire une recherche aléatoire dans l'un des deux fichiers

Le programme ci-dessous permet d'ouvrir en lecture "especes.txt" OU "taxons.txt".

Le code :

#nom programme : ouvrir_aleatoire.py
# objet : recherche aléatoire dans un fichier
import random
nom_fichier =input("Tapez 'especes.txt' ou 'taxons.txt' : ")
reponse ="o"
with open(nom_fichier, "r") as fichier: 
   liste = fichier.readlines()
reponse = "o"
while reponse in "oO":
    element =random.choice(liste)
    print (element)
    reponse =input("Encore un tirage au sort  O/N ? " )
fichier.close()

Le fichier choisi est ouvert en lecture seule.
La méthode readlines() retourne tout le contenu du fichier sous forme d'une liste.
Grâce à la méthode choice() du module random on tire au sort l'un des éléments de la liste.
Trace d'exécution :

Tapez 'especes.txt' ou 'taxons.txt' : taxons.txt éponges Encore un tirage au sort O/N ? o poissons osseux Encore un tirage au sort O/N ? o bryozaires Encore un tirage au sort O/N ? o gastéropodes Encore un tirage au sort O/N ? o mollusques Encore un tirage au sort O/N ? n

Ouvrir un fichier en lecture-écriture

C'est possible à condition que le deuxième paramètre de la méthode open() soit "r+"
Ci-dessous programme qui permet d'ouvrir "especes.txt" ou "taxons.txt".
Le contenu actuel du fichier est d'abord affiché. Ainsi l'utilisateur a un pense-bête : en fonction du contenu il sait quoi ajouter éventuellement.
Puis il peut ajouter des lignes au fichier

Première version

Le programme ci-dessous ouvre en lecture/écriture "especes.txt" OU "taxons.txt".

Le code

#nom programme : ouvrir_en_lecture_ecriture.py
# objet : ouvrir le fichier de données 'especes' ou 'taxons' en lecture /ecriture
nom_fichier =input("tapez 'especes.txt' ou 'taxons.txt' : ")
with open(nom_fichier, "r+") as fichier:
       contenu = fichier.readlines()
       print(type(contenu))
       #contenu est de type 'list'		# instruction provisoire
       print("contenu actuel du fichier: ")
       print(contenu)
       reponse ="o"
       print()
       reponse =input("Voulez vous ajouter une espèce / un taxon o/n ? ")
       while reponse  in "oO":
                ajout =input ("Nom de l'espèce / du taxon : ")
                ajout = "\n" + ajout
                fichier.write(ajout)
                reponse =input( "Encore un ajout o/n  ? : " )
fichier.close()

Trace d'exécution du programme

Tapez 'especes.txt' ou 'taxons.txt' : especes.txt <class 'list'> contenu actuel du fichier: ['calmar\n', 'patelle\n', 'Pouple\n', 'Moule commune\n', 'Huitre creuse\n', 'Huitre plate\n', 'Balane\n', 'Crevette grise\n', 'Bouquet\n', 'Sole\n', 'Bar\n', 'Crabe vert\n', 'Étrille\n', 'Tourteau\n', 'Arénicole\n', '\n', 'morue'] Voulez vous ajouter une espèce / un taxon o/n ? o Nom de l'espèce / du taxon : plie Encore un ajout o/n ? : n

Analyse du code

with open(nom_fichier, "r+") as fichier : le deuxième argument de la méthode open est "r+"

Critiques

Ce programme est souple : on peut lire tout le contenu d'un fichier et ensuite, si on le souhaite, on peut écrire dans ce fichier.
Problème : le contenu du fichier est difficile à lire à cause de symboles 'parasites' : guillemets internes, virgules internes, retour chariot. Il faudrait pouvoir supprimer ces symboles ...

Version améliorée

La métthode readlines() retourne une liste. Il faudrait pouvoir convertir cette liste en chaine. Nous avions vu dans le chapitre 8 que c'est possible grâce à la méthode join() appliquée à la liste.

Extrait du code de la nouvelle verson

...
       contenu = fichier.readlines()
       contenu =" ; ".join(contenu)
       contenu =contenu.replace("\n", " ")
       print("contenu actuel du fichier: ")
...

La liste "contenu" est convertie en chaine grâce à la méthode join() ; dans cette chaine les mots sont séparés par des " ;".
Puis on remplace les symboles "\n" -c'est à dire les retours chariot - par des espaces : emploi de la méthode replace().

La trace d'exécution

Tapez 'especes.txt' ou 'taxons.txt' : taxons.txt Contenu actuel du fichier: Éponges ; Cnidaires ; Cténaires ; Vers ; Crustacés ; Échinodermes ; Bryozoaires ; Urocordés ; Poissons osseux ; Poissons cartilagineux ; Gastéropodes ; Bivalves ; Céphalopodes ; Cirripèdes ; Décapodes ; Cétacés ; Pinnipèdes ; échinodermes ; Anémones ; Amphipodes ; Méduses Voulez vous ajouter une espèce / un taxon o/n ? o Nom de l'espèce / du taxon : coraux Encore un ajout o/n ? : n

Reconnaissez que l'affichage du contenu est beaucoup plus clair.

La méthode writelines()

Le fichier ci-dessous permet d'ouvrir "especes.txt".

Exemple de programme basé sur cette méthode

# nom du programme : writelines.py
# ajout de plusieurs lignes à un fichier txt
with open ("especes.txt", "r+") as fichier:
        ligne = fichier.readline()      # lire première ligne du fichier
        print("contenu initial : ")
        while ligne != "":
                print(ligne, end =" ")
                ligne = fichier.readline() #lire ligne suivante

        # ajouts
        donnees = ["Roussette\n","Hareng\n","Merlan\n"]
        fichier.writelines(donnees)
  
        fichier.seek(0)
        print("nouveau contenu :")
        ligne = fichier.readline()      # lire première ligne du fichier
        while ligne != "":
                print(ligne, end =" ")
                ligne = fichier.readline() #lire ligne suivante
fichier.close()

Analyse du code

Le fichier "especes.txt" est ouvert en mode "r+" : lecture et écritue.
On lit séquentiellement le fichier avec une boucle basée sur readline() pour afficher le contenu inital du fichier.

La variable "données" référence une liste comprennant trois éléments, il pourrait y en avoir 300 ...
Grâce à une commande basée sur la méthode writelines(liste) le contenu de cette liste est ajouté au fichier sous forme de 3 lignes.

fichier.seek(0) : suite aux ajouts le pointeur est en EOF (End Of File) ; grâce à l'instruction "seek(0)" il (je parle du pointeur) sélectionne de nouveau la première ligne.
Pour terminer, on lit de nouveau séquentiellement le fichier, donc on affiche le contenu final.

Fin de ce chapitre !

Vous verrez prochainement que l'on peut manipuler en Python non seulement les fichiers .txt mais aussi les fichiers .csv