Garder la mémoire
Image par Tobias Dahlberg de Pixabay
Vous avez réussi à faire une liste de dictionnaires pour conserver le contact. Même si votre programme est très satisfaisant, il possède un défaut majeur. Quand vous quittez le programme, l'ensemble de vos contacts disparait avec la mémoire du programme. Les données étaient stockées dans la RAM de l'ordinateur et à la fin de l'exécution du programme, cet espace est libéré.
Quand bien même vous pourriez garder le programme en fonctionnement, il faudra bien un jour éteindre l'ordinateur
Il faut faire passer ces données de la RAM,qui est une mémoire volatile, vers une mémoire à plus long terme. Le système de fichier du disque dur est tout à fait adapté pour cela.
Mécanisme de base pour écrire dans des fichiers
Python fournit un mécanisme de base d'entrée sortie pour accéder aux fichiers. Nous allons voir quelques fonctions simples, avec leurs paramètres qui nous permettront de lire et d'écrire dans un fichier
L'ouverture du fichier
La première chose à faire est d'ouvrir le fichier auquel on veut accéder. Cette ouverture se
fait simplement grâce à la fonction open
qui prend deux paramètres
fichier = open(filename,mode)
Le premier paramétre est le nom du fichier que l'on veut ouvrir. Le second paramètre est le mode d'ouverture. En effet, on peut ouvrir le fichier de différente façon
Mode | Signification | |
---|---|---|
type d'ouverture | 'r' | (abbréviation de read) Ouverture du fichier en lecture. On ne peut que le lire, pas écrire dedans. C'est le mode par défaut si le paramètre de mode n'est pas précisé |
'w' | (abbréviation de write). Si le fichier n'existe pas, il est créé. Sinon, il est ouvert en écriture et son contenu actuel est supprimé. | |
'a' | (abbréviation de append). Ouvre le fichier en écriture, comme le mode 'w', mais au lieu de supprimer le contenu existant, le nouveau contenu sera ajouté à la fin du contenu existant | |
'x' | (abbréviation de exclusive. Fonctionne comme 'w' mais en mode de création exclusive. Ce mode provoquera une erreur si le fichier existe déjà. | |
type de fichier | 't' | Fichier de type texte. C'est le mode par défaut si rien n'est indiqué. |
'b' | Fichier binaire, c'est à dire qui peut contenir des données arbitraires (des images, du son, etc). Les données sont considéres comme des bytes, sans décodage. |
si par exemple on veut ouvrir en écriture un carnet d'adresse pour l'enregistrer, que le nom du fichier est
contacts.txt
, la commande a éxécuter sera la suivante :
fichier = open("contacts.txt",'wt')
Si après on veut relire le fichier pour importer son contenu, il suffira d'utiliser :
fichier = open("contacts.txt")
Comme on a pas indiqué de mode, on a le mode par défaut, c'est à dire 'rt'
(lecture d'un fichier texte).
À faire vous même
- On a un fichier où l'on consigne des informations journalisées (des logs), c'est
à dire des évènements qui arrivent dans un programme (par exemple telle personne a accédé à
telle ressource, telle personne s'est identifiée..). On veut ouvrir le fichier
prog.log
pour rajouter des lignes de texte d'information dedans. Quelle commande doit on utiliser ? -
On veut ouvrir un fichier d'image pour le transformer. Quelle commande permet
d'ouvrir le fichier
perroquet.jpg
pour le lire ?
- On en doit pas supprimer les anciens logs mais en ajouter de nouveau. On doit donc
ouvrir en mode
append
. C'est du texte qui est utilisé. On peut mettre let
ou pas (puisque c'est le paramètre par défaut)fichier = open("prog.log",'a')
-
Une image est un fichier binaire. On veut la lire. Le mode sera donc
'rb'
fichier = open("perroquet.jpg",'rb')
Fermeture du fichier
La fonction open
renvoie un objet de type fichier. On sauvegarde cet objet dans la variable
fichier
(qui pourrait avoir n'importe quel nom). Lorsque le fichier est ouvert, il ne va pas
être accessible pour d'autres programmes. C'est pour cela que dès que l'on a fini d'utiliser le fichier, il
faut bien penser à le ferme, grâce à la méthode close
fichier.close()
Écriture dans le fichier
Pour écrire dans le fichier, on utilise la méthode write
surl'objet fichier. Pour tous le reste de
ce document, on considérera que l'on est en mode texte. Pour écrire du texte, on va utiliser
fichier.write("Ce texte est écrit dans le fichier")
La fonction write
va écrire les données les unes à la suite des autres. Si on veut
aller à la ligne dans le fichier, il faut penser à rajouter le caractère de fin de ligne (\n
)
dans la chaine de caractère que l'on veut utiliser. On va utiliser le programme suivant pour écrire le
début de notre fichier
fruits = ['orange','ananas','kiwi','abricot']
fichier = open("fruits.txt",'w')
for fruit in fruits:
fichier.write(fruit+'\n')
fichier.close()
print("Le fichier est enregistré")
À faire vous même
Vous allez utiliser le code ci dessus pour créer un fichier contenant votre liste de fruits. Vous téléchargerez votre fichier etvous vérifirez son contenu dans un éditeur de texte quelconque.
Lire dans le fichier
Il y a trois façons de lire dans un fichier. Chacune correspond à un usage différent.
La méthode read
: cette méthode lit la totalité du fichier d'un seul coup
et va renvoyer l'ensemble sous forme d'une unique chaine texte.
fichier = open("fruits.txt")
contenu = fichier.read()
# la variable contenu vaut pour notre exemple "orange\nananas\nkiwi\nabricot\n"
fichier.close()
print(contenu)
La méthode readlines
: cette méthode var lire elle aussi la totalité du
fichier, mais elle va renvoyer le résultat sous forme d'un tableau, chaque case du tableau
contenant une ligne du fichier. On peut donc après effectuer une boucle for sur le tableau
qui agira sur chaque ligne du fichier.
fichier = open("fruits.txt")
lignes = fichier.readlines()
# la variable lignes vaut pour notre exemple ['orange\n','ananas\n','kiwi\n','abricot\n']
fichier.close()
for element in lignes:
element = element.rstrip("\n") #on enlève le saut de ligne à la fin
if element =="kiwi":
print("j'adore le kiwi")
else:
print(f"J'aime bien l'{element} mais je préfère le kiwi !")
La dernière méthode est readline
(sans le s). Cette méthode est surtout
utilisée lorsque le fichier est un fichier de grande taille et que l'on ne veut pas charger
l'intégralité d'un fichier en mémoire d'un seul coup. Par exemple, les journaux qui représentent
les accès à un serveur web peuvent facilement représenter plusieurs Go de données. Charger
le fichier en mémoire d'un seul coup prendrait plusieurs Go d'espace dans la mémoire vive, ce qui
n'est pas souhaitable. On utilise la méthode readline
au sein d'une boucle while
.
En effet, à la fin du fichier, readline
renvoie une chaine vide (alors qu'une ligne vide
renvoie "\n")
fichier = open("fruits.txt")
# on lit ligne par ligne
ligne = fichier.readline()
while ligne !="":
ligne = ligne.rstrip("\n") # on enlève le saut de ligne à la fin
if ligne =="kiwi":
print("j'adore le kiwi")
else:
print(f"J'aime bien l'{ligne} mais je préfère le kiwi !")
ligne = fichier.readline() # lecture de la ligne suivante
# on ne ferme qu'après avoir tout lu
fichier.close()
Lire et écrire en utilisant with
Le langage Python permet d'utiliser, pour accéder aux fichiers, un élément syntaxique qui encadre
ce que l'on fait sur le fichier et se chargera de le ferme à la fin, même s'il y a un problème :
with
.
l'expression with
encadre un bloc qui contient tout ce qui sera fait sur la fonction. Nos
exemples deviennent plus simples pour lire et écrire, et plus sécurisés
Écriture du fichier
fruits = ['orange','ananas','kiwi','abricot']
with open("fruits.txt",'w') as fichier :
for fruit in fruits:
fichier.write(fruit+'\n')
print("Le fichier est enregistré")
On voit que l'on a pas eu à gérer la fermeture du fichier.
Lecture du fichier
On peut bien entendu utiliser la même syntaxe pour
accéder aux fichiers avec with
afin de les lire
(avec read
et readlines
) en une fois.
Très souvent, on préfère lire les fichiers ligne par ligne, cela fonctionnant
aussi avec les gros fichiers. On peut alors utiliser une boucle for
ce qui allégera la syntaxe. En utilisant
for ligne in fichier:
On aura accés à chaque ligne du fichier successivement
Le dernier exemple ci dessous va d'abord ouvrir le fichier pour écrire dedans, le fermer, puis l'ouvrir en lecture pour le lire ligne à ligne
fruits = ['orange','ananas','kiwi','abricot']
with open("fruits.txt",'w') as fichier :
for fruit in fruits:
fichier.write(fruit+'\n')
print("Le fichier est enregistré")
with open("fruits.txt") as fichier:
for ligne in fichier:
ligne = ligne.rstrip("\n")
print(f" nouveau fruit: {ligne}")
print("le fichier a été lu et affiché")
En résumé ...
Relisez les paragraphes ci dessus et faites une fiche de résumé qui montre un programme qui fait toutes les actions suivantes :
À retenir
- Ouverture d'un fichier
- Indiquer les différents modes d'ouverture
- Écriture dans un fichier
- Lecture dans un fichier (read,readlines et readline)
- Utilisation de with
Mini projet d'annuaire de contacts
Maintenant que nous savons écrire dans un fichier, nous allons pouvoir créer notre fichier de contact. Ce qui est dans la mémoire de l'ordinateur pourra être sauvegardé. Ainsi, lorsque l'on quitte l'application, on ne perdra plus l'ensemble de nos données.
Vous allez compléter le fichier qui est donné ci après. Vous avez juste 5 fonctions à compléter. Le fonctionnement en est simple :
- Une fonction sert pour ajouter un contact. Elle demande à l'utilisateur toutes les informations (nom, prénom, adresse mail, téléphone, adresse postale, compte instagram, compte snapchat, surnom) et renvoi toutes ces informations sous forme d'un dictionnaire (qui pourra être ajouté à la liste des contacts)
- Une fonction affiche tous les contacts. Elle affiche leur numéro dans la liste et peut être une partie seulement des informations (par exemple nom, prénom et téléphone)
- Une fonction permet de visualiser le détail d'un contact
- Une fonction permet de supprimer un contact
-
Enfin, une fonction permet de sauvegarder l'ensemble du carnet d'adresse. Voici le fonctionnement attendu :
- pour chaque contact, elle commence par indiquer le numéro du contact encadré par des tirets
(par exemple :
----- contact n° 17 -----
) -
Pour chaque entrée du dictionnaire correspondant au contact,
elle ajoute une ligne dans le fichier avec la clef suivie de
: et de la valeur associée (par exemple
nom : Durand
)
- pour chaque contact, elle commence par indiquer le numéro du contact encadré par des tirets
(par exemple :
Tant que le programme tourne, il vous propose un choix : ajouter, lister, détail, suppression ou quitter. Au moment de quitter, il sauvegarde les contacts dans un fichier dont vous choisissez le nom.
PS : vous pouvez vous servir du code que vous avez réalisé pour le chapitre précédent, qui gérait les dictionnaires de contact
PPS : vous pouvez travaillez dans le navigateur ou utiliser un IDE comme visual studio code si vous préférez. Si vous travaillez dans le navigateur, pensez à sauvegarder régulièrement votre travail en téléchargeant le script
Et le chargement ?
Vous avez peut être remarqué : à la fin de notre programme nous sauvegardons la liste de contacts. Nous ne perdons plus la mémoire. La liste de contact est sauvegardée dans un fichier que vous pouvez lire (à la fin de l'activité, vous avez pu créer votre fichier et le sauvegarder sur votre ordinateur)
Mais nous n'avons pas prévu d'importer notre fichier de contacts dans notre programme. C'est dommage, ce serait une fonctionnalité très intéressante. Oui, mais voilà, la façon dont nous avons enregistré les contacts ne s'y prête pas trop. Il faudrait parcourir le fichier ligne par ligne et recréer chaque dictionnaire.
C'est possible. Mais ce n'est pas le plus pratique, de très loin.
Nous allons voir qu'il existe une autre façon d'enregistrer les fichiers dans le chapitre suivant.