1- Introduction à la manipulation de fichiers
Vous aurez sans doute l’occasion d’être confronté, de manière régulière, à de la gestion de données plus ou moins massives. Qu’elles proviennent de capteurs ou d’informations d’utilisateurs, les données sont en fait absolument essentielles à n’importe quel projet. Plus encore, depuis quelques années, on s’intéresse au Big Data où, cette fois-ci, les données deviennent des marchandises que l’on peut s’échanger et qui possèdent une grande valeur.
Pourtant, traiter un grand volume de données n’a pas toujours été facile dans l’histoire de l’informatique. Aujourd’hui, à l’heure du tera-octet de données sur un ordinateur portable, on développe des jeux ou des programmes de plusieurs giga-octets. Pourtant, quelques années en arrière, on comptait encore en kilobits, kilo-octet ou autres unités qui nous semble maintenant désuètes. Il serait bon parfois de repenser à cet ancien temps où le travail du développeur était d’optimiser ses programmes et où cette dernière jouait en rôle absolument essentiel dans la qualité d’un programme.
Bref, aujourd’hui, tout cela est dépassé. On peut traiter plusieurs tera-octets de données sans que cela ne choque plus personne. On a su développer des outils performants nous permettant de traiter de tels volumes de données. Ces outils, on les utilises d’ailleurs parfois à torts et à travers, on utilise la hache pour abattre une tulipe.
L’idée de la manipulation de fichier, c’est de stocker des données sous une autre forme que celle d’une base de données par exemple. En fait, c’est d’être capable de les enregistrer dans un fichier texte de manière formatée et d’être ensuite capable de travailler sur ce fichier. Cela a pour avantage de ne pas nécessiter la mise en place d’un serveur de base de données et donc de faire gagner plus ou moins de temps dans la réalisation de nos « petits » projets personnels.
J’insiste. L’idée de ce tutoriel est bien de nous porter sur la manipulation de fichier d’une manière basique. Je n’aborderai pas les notions de JSON ou la manipulation de feuilles de calculs excel (pourtant très utiles par ailleurs). Peut-être cela viendra-t-il plus tard mais on peut aussi se dire que dès lors que les données sont « importées » dans Python, alors on est théoriquement capable de faire tout le traitement…
L’avantage de ce tutoriel, c’est qu’il ne nécessite aucune bibliothèque. De plus, il est là pour poser les bases d’une série de tutoriels en préparation et qui nécessitera de maitriser les fichiers et les données diverses et variées de manière agile afin d’être en mesure de se consacrer sur le traitement en lui-même. Croyez-moi, en préparant ce tutoriel, vous prendrez une avance essentielle sur la suite et pourrez donc suivre la série de manière plus « détendue »…
2- Manipulons des fichiers
A- Création d’un fichier et écriture
Il est alors temps de nous lancer, de créer notre propre fichier. Pour cela, deux moyens s’offrent à nous. Le premier, c’est créer bêtement un fichier texte dans lequel on rentre nos données manuellement. Le second, c’est de créer ce même fichier depuis Python, cela aura pour avantage de nous permettre une génération pseudo-aléatoire (l’aléatoire en informatique est une notion bien délicate).
Bien sûr, vous avez aussi la possibilité d’utiliser un fichier que vous aurez généré par exemple depuis votre Arduino lors de l’acquisition de données et de leur enregistrement sur une carte SD.
La création d’un fichier nécessite de connaitre les trois modes d’ouverture d’un fichier depuis Python :
r | Ouverture du fichier en mode lecture uniquement |
w | Ouverture du fichier en mode écriture seulement |
a | Ouverture du fichier en mode ‘append’, c’est-à-dire que l’on ajoute du contenu en fin de fichier |
Mais quelle est donc la différence entre le mode ‘w’ – write – et ‘a’ – append ?
En fait, la différence réside dans l’idée que le mode écriture permet d’écrire dans le fichier en écrasant ce qu’il contient déjà. Le mode ajout quant à lui permet de rajouter du contenu en fin de fichier, en préservant ce qui est déjà enregistré.
L’ouverture d’un fichier en Python s’effectue à l’aide de la commande suivante :
file = open(chemin_vers_le_fichier, mode_d_ouverture)
Par exemple :
file = open(‘donnees_meteo.txt’, ‘w’)
Aussitôt la fonction open() introduite, je tiens à introduire la fonction close(). De la même manière que l’on range un livre après l’avoir pris dans la bibliothèque, on doit « ranger » le fichier que l’on a édité. C’est précisément ce que permet la fonction close, elle s’utilise alors de la manière suivante :
file.close()
En reprenant la notation introduite pour l’ouverture du fichier.
Pour écrire dans le fichier, cela reste relativement facile en utilisant la fonction ‘write’ à bon escient de la manière suivante :
file.write(‘Hello world !’)
On peut alors utiliser les caractères « \n » et « \r » pour insérer des retours à la ligne / retour chariot afin de formater un minimum notre fichier.
\n | New line – Nouvelle ligne | Permet de revenir à la ligne (équivalent d’un appui sur la touche entrée sur Word ) |
\r | Carriage return – Retour chariot | Renvoie le curseur d’écriture en début de ligne |
Pour résumer cette première partie, voilà le code qui m’a permis de créer un fichier « premier_fichier.txt » dans le même répertoire que mon script Python.
file = open("premier_fichier.txt", "w")
file.write("Hello world !")
file.close()
B- Lecture d’un fichier
Vous êtes donc désormais en mesure de créer et d’éditer un fichier mais l’utilité serait bien faible si l’on ne pouvait pas le lire à nouveau ensuite. La méthode de lecture d’un fichier est très semblable à celle de l’écriture. L’idée est toujours d’ouvrir le fichier puis de travailler dessus. Cependant, il n’est pas forcément très facile de traiter les données qui arrivent du fichier. On récupère le plus souvent une chaine de texte brute contenant l’ensemble du fichier, dans le meilleur des cas un tableau contenant chacune des lignes. L’objectif est alors d’effectuer un pré-traitement permettant de formater correctement les données.
Ainsi, pour ce tutoriel, j’ai décidé de vous montrer de quelle manière on pouvait passer d’un fichier semblable au suivant dans sa structure :
Numero_du_point, abscisse, ordonnée
Numero_du_point, abscisse, ordonnée
Numero_du_point, abscisse, ordonnée
Numero_du_point, abscisse, ordonnée
etc...
A un simple tableau contenant chacune des lignes et les présentant sous la forme d’une liste [Numero_du_point, abscisse, ordonnée]. Si l’exemple n’est pas général, j’ai pensé que c’était cependant un cas qui se présentait assez souvent. En effet, lors de l’enregistrement des données, par exemple depuis l’Arduino, on est en fait assez libre de la manière de le faire. On peut ainsi insérer facilement un séparateur (, ; . ! etc…) entre les différentes valeurs, ce qui permettra alors de retrouver plus aisément ensuite la liste originale des valeurs.
Partant donc d’un fichier semblable à celui présenté ci-dessus, on se propose de l’ouvrir en mode écriture :
fichier = open(‘mesures_altitude.txt’, ‘r’)
Désormais, on a alors accès à l’intégralité des fonctions liées aux fichiers sur Python. On a alors un choix à faire. On peut choisir de lire l’intégralité du fichier et de stocker son contenu dans une variable sous la forme d’une chaine de caractères, ou alors on peut lire chacune des lignes et les stocker dans une liste que nous pourrons parcourir par la suite. C’est la second méthode que j’ai choisi ici mais vous pourrez utiliser la première à l’aide de la structure suivante et en utilisant astucieusement les quelques fonctions que je présenterai par la suite :
contenu = fichier.read()
Pour adopter ma méthode, on utilisera plus simplement la structure suivante :
lignes = fichier.readlines()
Alors, chaque ligne sera stockée dans une grande liste et sera terminé par un classique « \n » spécifiant un retour à la ligne. On a alors l’avantage de pouvoir itérer, c’est-à-dire parcourir, chacune des lignes en utilisant la structure suivante :
for ligne in lignes :
# Faire quelque chose
Et je vous propose alors simplement d’afficher la ligne courante de la manière suivante :
for ligne in lignes :
print(ligne)
Vous remarquerez alors la présence d’un double retour à la ligne (retour à la ligne + saut de ligne) à chaque affichage.
point_1, 9, 10
point_2, 6, 8
point_3, 1, 5
point_4, 6, 1
point_5, 9, 0
Pour gérer cela, je dois vous présenter la fonction replace() s’appliquant à une chaine de caractère. Elle s’utilise en spécifiant deux arguments. Le premier est le bout de chaine de caractère à remplacer. On peut aussi spécifier une expression régulière mais le sujet est alors bien trop vaste pour être détaillé ici. Le second argument quant à lui constitue la chaine de caractère de remplacement, c’est-à-dire celle qui viendra se substituer au bout de chaine de caractère que l’on souhaite remplacer.
Dans notre cas, le double retour à la ligne est en fait causé par le « \n » dont je vous ai parlé auparavant. On peut résoudre ce problème à l’aide de la structure suivante :
for ligne in lignes :
ligne = ligne.replace(‘\n’, ‘’)
print(ligne)
et l’on obtient alors dans mon cas l’affichage suivant :
point_1, 9, 10
point_2, 6, 8
point_3, 1, 5
point_4, 6, 1
point_5, 9, 0
Enfin, j’ai parlé au début de récupérer les points sous la forme d’une liste [numero, x, y]. Etant donné que mon fichier est correctement formaté, on peut directement utiliser la fonction split() qui s’utilise en spécifiant un argument, le séparateur, autour duquel on viendra « découper » notre chaine. Dans mon cas, le séparateur est « , » (j’insiste sur l’espace suivant la virgule). On utilise alors la syntaxe suivante pour former notre liste :
for ligne in lignes:
ligne = ligne.replace('\n', '')
donnees = ligne.split(', ')
print(donnees)
Ici, j’ai fait le choix d’afficher les données mais l’on pourrait tout autant poursuivre le traitement (d’autant qu’à ce moment précis, donnees contient mes données sous la forme de 3 chaines de caractères, bien peu utile pour du traitement mathématique par exemple. On peut alors convertir les chaines de caractères à l’aide des classique fonctions de conversion de type (int(), float(), etc…)
Il nous reste alors à mettre en place un traitement des données, ce sera précisément l’étude que nous mènerons dans de prochains tutoriels.
3- Conclusion
J’espère au travers de ce tutoriel, être parvenu à vous présenter les bases de la manipulation de fichiers en Python. L’idée n’est certainement pas de maitriser l’ensemble des outils existants pour de tels traitement. Au contraire, j’ai volontairement choisi de présenter les bases de la manipulation de fichiers et ce pour pouvoir m’attarder plus longuement sur le traitement à l’aide d’algorithme plus complexes.
Les fichiers textes ne sont pas les seuls moyens de stockage de données. Il me semble absolument essentiel de vous parler de la gestion de données via base de données SQL au sein d’un prochain tutoriel.
Ce que vous avez appris ici vous servira sans doute de manière courante en Python et, en tous les cas, vous permettra d’aborder plus sereinement certains de nos tutoriels.
Fabien A.
Super Bravo !
Même si le sujet est relativement connu, c’est très agréable de l’avoir sous cette forme claire et agréable à lire.
Je suis impatient de découvrir les autres tutoriels, en particulier ceux qui concerneront la gestion des bases SQL et les fichiers Excel.
Un grand Merci !
On vous prépare ça très bientôt 😉
Super ! Encore merci !
D’abord: MERCI !
Application pratique :
Je débute avec python mais pas en programmation, j’ai écrit un petit logiciel de messagerie avec smtplib c’est très bien, mais du coup j’avais la configuration en dure.
Maintenant j’ai un joli fichier de configuration séparé et c’est grâce à cet article ;-).
Bravo très explicite
Bonjour,
J’ai essayé votre méthode replace pour modifier des lettres avec accent par des lettres sans accent dans un fichier, par exemple les « é » en « e » etc..
Mais je n’ai réussi à le faire que pour une lettre, je n’arrive pas à effectuer toutes les modifications, pouvez-vous m’aider s’il-vous-plaît ?
Je vous remercie
Bonjour,
Je n’ai pas bien compris votre problème. Vous souhaitez effectuer plusieurs remplacement à la suite ? Si oui, vous avez simplement à procéder de la manière suivante:
for ligne in lignes:
ligne = ligne.replace(‘\n’, »)
ligne = ligne.replace(‘é’, ‘e’) # Remplace les é en e
ligne = ligne.replace(‘è’, ‘e’) # Remplace les è en e
donnees = ligne.split(‘, ‘)
print(donnees)
Bien sûr, ce n’est ici qu’un exemple et il faudra adapter à votre situation.
Si vous souhaitez remplacer tout une chaine de caractère, on peut utiliser les expressions régulières mais c’est un poil plus complexe 😉
A bientôt
merci c’était cool mais j’ai pas lue