Accueil

Traduction

Tutoriel Python - sommaire

Tutoriel Python - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Python et les fichiers texte (.txt)

Dès que vous fermez un programme les données contenues dans les variables et les séries itérables sont perdues.
Pour stocker de façon permanente des données on pense aux bases de données. Mais pour de nombreuses applications, utiliser une BD alors qu'il n'y a que quelques données à stocker, c'est "tuer une mouche avec un canon".

Les fichiers texte

Une espèce appartient à un taxon (groupe d'espèces ayant un ancêtre commun) et un seul.

Ces fichiers ont été enregistrés dans le dossier c:/python_prog. Donc dans le même dossier que les scripts Python.

Contenu du fichier "taxons.txt"

éponges
Cnidaires
Cténaires
Vers
Crustacés
Echinodernes
Bryozaires
Urocordés
Poissons osseux
Poissons cartilagineux
Gastéropodes
Bivalves
Cephalopodes
Cirripèdes
Décapodes
Cétacés
Pinnipèdes
échinodermes
Anémones
Amphipodes
Méduses

Contenu du fichier "especes.txt"

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

Structure des fichiers

Dans chaque fichier une donnée (espèce ou taxon) par ligne.
Ces fichiers sont encodés en ANSI ainsi les lettres accentuées seront affichées proprement.

Manipuler les fichiers texte en mode interactif

Avant de passer à la programmation nous allons manipuler ces fichiers via la console Python.
Vous verrez qu'on peut déjà faire pas mal de choses ...

Accéder au bon dossier

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

J'ai importé le module os ( OS comme Operating System).
Ce module propose des méthodes qui permettent de manipuler fichiers et dossiers.
La fonction os.getcwd() précise le répertoire courant. Notez qu'il s'agit du dossier 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 c'est à dire c:\Python39

Ouvrir et lire le fichier "especes.txt"

Mes fichiers texte sont dans un autre dossier que le répertoire courant ; ils sont dans : c:\python_prog. Il faut donc changer de "directory" (répertoire).

os.chdir("c:/python_prog") : accès au répertoire qui contient mes programmes et fichiers.
fichier = open("especes.txt", "r") : ouvrir le fichier "especes.txt" en lecture seule ("r") et créer un objet de type "file" (nommé ici "fichier"). On peut appliquer à cet objet "file" différentes méthodes.
fichier.readlines() : la méthode readlines() appliquée à un "ObjetFile" retourne la totalité du contenu du fichier sous forme d'une liste à raison d'un élément de liste par ligne.
Notez que chaque élément de la liste se termine par '\n' (caractère qui commande un saut de ligne).

Dans tous les exemples de ce chapitre, l'objectFile sera nommé "fichier".
Remarque : c'est la fonction native open() qui crée un objectFile.

Ouvrir et lire le fichier "taxons.txt"

On suppose bien sûr qu'on est toujours dans le bon répertoire.

Notez la nouvelle 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. En effet, si pour une raison ou une autre, l'ouverture ou la lecture du fichier conduit à une erreur, l'utilisation de la syntaxe "with open … as objectFile" garantit une fermeture effective du fichier.
L'instruction "with open ..." crée un bloc d'instructions. Les commandes de manipulation du fichier doivent être dans ce bloc ; donc doivent être indentées.
À la sortie du bloc il y a fermeture automatique du fichier. Donc la commande objectFile.close() devient inutile !

Lire un fichier avec la méthode read()

>>> with open('especes.txt','r') as fichier :
...     contenu = fichier.read()
...
>>> print(contenu)
Seiche
Calmar
Moule commune
Huitre creuse
Huitre plate
Balane
Crevette grise
Bouquet
Sole
Bar
...

La méthode read() lit la totalité du contenu du fichier et retourne le contenu sous forme d'une chaine de caractères unique ici récupérée dans la variable "contenu".
print(contenu) : la chaine est affichée sur plusieurs lignes grâce aux (\n) à la fin de chaque ligne du fichier.
On obtient donc un affichage plus satisfaisant qu'avec readlines()

Lire un fichier avec la méthode readline()

La méthode readline() (sans s à la fin) lit seulement une ligne du fichier et la retourne sous forme d'une chaine.
Donc le premier appel de cette méthode lit la première ligne, le deuxième appel lit la seconde, etc.

>>> with open('taxons.txt','r') as fichier :
...     ligne = fichier.readline()
...     while ligne !="" :
...             print(ligne)
...             ligne =fichier.readline()
...
éponges

Cnidaires

Cténaires
...

Pour lire successivement les lignes du fichier il faut une commande "readline()" avant la boucle et une deuxième dans la boucle.
L'itération s'effectue tant que la fin de fichier n'est pas détectée.
Notez les lignes vierges ... Il y a en effet le saut de ligne du print() et le saut de ligne provoqué par le caractère "\n".

Lire un fichier sans utiliser une des trois méthodes

Ces trois méthodes sont surtout utiles en mode console : elles permettent de lire un fichier (ou une ligne) sans recourir à une boucle et à la commmande print().
Mais sachez qu'un objectFile peut être parcouru par une boucle.

>>> with open('taxons.txt','r') as fichier :
...     for ligne in fichier :
...             print(ligne,end =" ")
...
éponges
 Cnidaires
 Cténaires
 Vers
 Crustacés
 Echinodernes
 Bryozaires
 ...
 

En mode programmé on préférera cette solution.
Remarquez que cette fois les lignes vierges ont disparu gràce au deuxième argument du print() qui supprime le saut de ligne par defaut de cette fonction.

Écrire dans un fichier texte

Créez avec NotePad un fichier texte vierge de tout contenu dans le dossier "c:/python_prog" et nommer le "vierge.txt".

Ajout de texte à ce fichier

>>> os.getcwd()
'c:\\python_prog'
>>> with open('vierge.txt','a') as fichier :
...     fichier.write("sole")
...     fichier.write("bar")
...     fichier.write("morue")
...
4
3
5
>>> with open('vierge.txt','r') as fichier :
...     fichier.readlines()
...
['barsolebarmorue']
>>>

os.getcwd() : on vérifie si on est toujours dans le bon répertoire.
with open('vierge.txt','a') as fichier : ouvrir le fichier en mode ajout.
fichier.write("sole") : ajout de cette chaine dans le fichier
On ouvre ensuite le même fichier en lecture et on constate qu'il y a un gros problème : les textes ont bien été ajoutés mais sans saut de ligne ; ils sont collés !

Remarque : la console affiche le nombre d'octes insérés par chaque "write".

Écrire avec écrasement de l'ancien contenu

Le fichier "vierge.txt" n'est plus vide mais contient des données qui ne nous satisfont pas.
Nous allons l'ouvrir en mode "w" afin que l'ajout écrase l'ancien contenu.

>>>with open('vierge.txt','w') as fichier :
...     fichier.write("sole \n")
...     fichier.write("bar \n")
...     fichier.write("morue \n")
...
6
5
7
>>>with open('vierge.txt','r') as fichier :
...     lignes = fichier.read()
>>>print(lignes)
sole
bar
morue

Cette fois le fichier contient bien 3 lignes de texte.
Si vous doutez, ouvrez ce fichier avec NotePad !

Récapitulons

La fonction with open() ...as ... crée un objectFile et exige deux arguments : le chemin du fichier texte, le mode d'ouverture du fichier.

Le chemin du fichier se résume à son nom si le répertoire courant est celui qui contient le fichier.

Manipuler un fichier texte dans le cadre d'un programmes

Le programme qui manipule un fichier texte et ce dernier doivent de préférence être dans le même répertoire ; ainsi le problème, parfois délicat, du chemin relatif sera résolu ; le premier argument de open() se résumera au nom du fichier.

Un programme qui gère un fichier associé à un jeu

Le programme lit un fichier qui contient le dernier score.
Le jeu se déroule et le score de la session est produit.
Le fichier est de nouveau ouvert pour enregistrez le nouveau score ; le contenu précédent est écrasé !

Le programme

Il lit l'ancien contenu du fichier texte puis écrit dans ce fichier le nouveau score et la date.

#nom du fichier : structure_jeu.py
import random
import os
import datetime as dt
courant = os.getcwd()
print(f"Répertoire courant : {courant}")
with open("score.txt","r") as fichier:
        contenu = fichier.read()
print(f"Votre ancien score : {contenu}")
score_session = 0
pseudo = input ("tapez votre pseudo : " )
for i in range(10):
        """ici il y aurait appel de la fonction
         correspondant à une partie
         fonction retourant le score d'une partie
         """
        score_partie = random.randint(1,11)
        score_session +=score_partie

# conservation du scrore de la dernière session 
print(f"votre nouveau score : {score_session} ")
cejour = dt.datetime.today()
datecourante = cejour.strftime("%H:%M:%d:%m:%Y")
contenu = " pseudo, date et score : " + pseudo + " " 
+ datecourante + " " + str(score_session)
with open("score.txt", "w") as fichier:
        fichier.write(contenu)

Attention le code correspondant à une partie est remplacée par la génération aléatoire d'un entier compris entre 1 et 10.
Une session de jeu c'est 10 parties d'où la boucle.

Affichage dans le shell

Répertoire courant : C:\python_prog
Votre ancien score :  pseudo, date et score : darche 15:34:10:08:2024 59
tapez votre pseudo : darche
votre nouveau score : 60 

À la différence du mode console, le répertoire courant est celui qui contient le script et ... aussi le fichier texte.

Programme basé sur writelines()

La méthode writelines() permet d'ajouter plusieurs lignes en une seule instruction. Voyons cette méthode au travers d'un programme.

L'utilisateur lit l'ancien contenu du fichier ; fait des ajouts puis lit le contenu actualisé par les ajouts.

Première version du script

# nom du programme : writelines.py
# ajout de plusieurs lignes à un fichier txt
print("Ancien contenu : ")
with open ("especes.txt", "r") as fichier:
        ancien_contenu = fichier.read()    
        print(ancien_contenu, end =" ")
print("-----------------------------------")
with open ("especes.txt", "a") as fichier:
        ajouts = ["Roussette\n","Hareng\n","Merlan\n"]
        fichier.writelines(ajouts)

print("Nouveau contenu : ")     
with open ("especes.txt", "r") as fichier:
        nouveau_contenu = fichier.read()
        print(nouveau_contenu, end =" ")

Il faut ouvrir trois fois le même fichier texte avec à chaque fois un mode différent.
C'est un peu lourd ...

Le rendu

On a bien rajouté trois lignes dans le fichier.

Nouvelle version du programme

Je vous propose maintenant une variante qui n'exige qu'une ouverture du fichier (et non pas trois).
Ce programme contient deux nouveautés syntaxiques utiles. et se nomme "writelines_bis.py".

# nom du programme : writelines_bis.py
with open ("especes.txt", "r+") as fichier:
    print("Ancien contenu :")
    for ligne in fichier :
            print(ligne,end =" ")
    print("--------------------------")
    ajouts = ["Roussette\n","Hareng\n","Merlan\n"]
    fichier.writelines(ajouts)
    fichier.seek(0)   # repointer le début du ficher
    print("Nouveau contenu :")
    for ligne in fichier :
        print(ligne,end =" ")

Les nouveautés :
... open ("especes.txt", "r+") as ... : le fichier est ouvert en lecture-écriture.
fichier.seek(0) : pointer le début de fichier. En effet après les ajouts le curseur pointe EOF (la fin de fichier).
Vous connaissez désormais quatre modes différents d'ouverture d'un fichier : r,a,w,r+
Vous connaissez maintenant sept méthodes applicables à un 'objectFile' : .close(), .read(), .readlines(), .readline(), .write(), .writelines(), .seek()

Le rendu

Avant de lancer la nouvelle version, ouvrez le fichier "especes.txt" avec NotePad, supprimez les trois dernières lignes ajoutées via la première version ("Roussette\n","Hareng\n","Merlan\n") puis fermez le fichier. Vous pouvez alors exécuter le nouveau script.

Le shell produit avec la variante :

Ancien contenu :
Seiche
 Calmar
...
 Tourteau
 Arénicole
  --------------------------
Nouveau contenu :
Seiche
 Calmar
 ...
 Tourteau
 Arénicole
 
 Roussette
 Hareng
 Merlan

Trois lignes ajoutées !
Vous pouvez aussi ouvrir le fichier texte avec NotePad pour constater les ajouts.

Programme pour lire un fichier caractère par caractère

Quand vous aborderez la programmation de jeux vidéos en Python vous verrez qu'il peut être utile de lire un fichier texte qui sert de modèle pour créer le décor du jeu : afficher tel ou tel sprite en fonction du caractère lu.

Le contenu du fichier texte "modele.txt"

MMMMMMMMMMMMMMMMMMMMMMMMM
M                       M
MMMMMMM MMMMM MMMM MMMM M
M                       M
MMMMMMMMMM MMMMMMMMMMMMMM
M      MMM MM           M
MMMM M        MM MMM M MM
M  M MMMMMMMMMMM MMM M  M
M  M           M MMM M  M
M  MMMMM MMMMMMM MMM MMMM
M                       M
M MMMMMMMMM MMMMMM MMMMMM
M             MM       MM
MMMMMM MMMMMMMMMMM MMMMMM
MM MMM M                M
MM MMM M MMMMMMMMMMMMM MM
MM MMM           MMMMM MM
MM MMMMMMMMMMMM MMMMMM MM
MM                     MM
MMMMMM     MMMMMMMM MMMMM
MMMMMM MMMMMM       MMMMM
M         MMM MMMMM     M
MMMMMMMMM MMM MMMMMM    M
M                  MMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMM

Chaque caractère est "M" ou " " (espace).

Il y a 25 lignes et chaque ligne comprend 25 caractères.

Le script de lecture du fichier texte

#nom du fichier : lire_modele.py
# script qui lit le fichier modele.txt 
with open("modele.txt", "r") as fichier:
  for ligne in fichier:
    for car in ligne:
      if car == 'M':
          print(car, end =' ')
      else  :
          print(' ',end=' ')       
    print()  # saut de ligne

Il faut donc deux boucles imbriquées : la boucle externe lit une ligne du fichier et la boucle interne lit chaque caractère de la ligne.
Notez que je n'utilise aucune méthode pour lire le fichier. Puisque l'objet "file" (nommé ici "fichier") est itérable j'utilise deux boucles pour lire chaque ligne et à l'intérieur de chaque ligne, chaque caractère.

Le rendu

Le shell affiche :

M M M M M M M M M M M M M M M M M M M M M M M M M   
M                                               M   
M M M M M M M   M M M M M   M M M M   M M M M   M   
M                                               M   
M M M M M M M M M M   M M M M M M M M M M M M M M   
M             M M M   M M                       M   
M M M M   M                 M M   M M M   M   M M   
M     M   M M M M M M M M M M M   M M M   M     M   
M     M                       M   M M M   M     M   
M     M M M M M   M M M M M M M   M M M   M M M M   
M                                               M   
M   M M M M M M M M M   M M M M M M   M M M M M M   
M                           M M               M M   
M M M M M M   M M M M M M M M M M M   M M M M M M   
M M   M M M   M                                 M   
M M   M M M   M   M M M M M M M M M M M M M   M M   
M M   M M M                       M M M M M   M M   
M M   M M M M M M M M M M M M   M M M M M M   M M   
M M                                           M M   
M M M M M M           M M M M M M M M   M M M M M   
M M M M M M   M M M M M M               M M M M M   
M                   M M M   M M M M M           M   
M M M M M M M M M   M M M   M M M M M M         M   
M                                     M M M M M M   
M M M M M M M M M M M M M M M M M M M M M M M M M   

On affiche un beau labyrinthe !