- Introduction
- Basic File IO in Python
- Reading Line by Line
- An Example Application
- Conclusion
Introduction
Au cours de ma vie professionnelle, j’ai eu l’occasion d’utiliser de nombreux concepts et technologies de programmation pour faire d’innombrables choses. Certaines de ces choses impliquent des fruits de mon travail à valeur relativement faible, comme l’automatisation des erreurs ou des tâches banales comme la génération de rapports, l’automatisation des tâches et le reformatage général des données. D’autres ont été beaucoup plus utiles, comme le développement de produits de données, d’applications web et de pipelines d’analyse et de traitement des données. Une chose notable dans presque tous ces projets est la nécessité d’ouvrir simplement un fichier, d’analyser son contenu et d’en faire quelque chose.
Cependant, que faites-vous lorsque le fichier que vous essayez de consommer est assez volumineux ? Que faire si le fichier contient plusieurs Go de données ou plus ? Encore une fois, cela a été un autre aspect fréquent de ma carrière de programmeur, qui s’est principalement déroulée dans le secteur BioTech, où il est courant de rencontrer des fichiers de plus de 1 To.
La réponse à ce problème est de lire des morceaux d’un fichier à la fois, de le traiter, puis de le libérer de la mémoire afin de pouvoir tirer et traiter un autre morceau jusqu’à ce que tout le fichier massif ait été traité. Bien qu’il appartienne au programmeur de déterminer une taille de chunk appropriée, pour de nombreuses applications, il convient de traiter un fichier une ligne à la fois.
Au cours de cet article, nous couvrirons un certain nombre d’exemples de code pour montrer comment lire les fichiers ligne par ligne. Au cas où vous voudriez essayer certains de ces exemples par vous-même, le code utilisé dans cet article peut être trouvé dans le repo GitHub suivant.
Les entrées-sorties de fichiers de base en Python
Etant un grand langage de programmation généraliste, Python possède un certain nombre de fonctionnalités d’entrées-sorties de fichiers très utiles dans sa bibliothèque standard de fonctions et de modules intégrés. La fonction intégrée open()
est ce que vous utilisez pour ouvrir un objet fichier à des fins de lecture ou d’écriture.
fp = open('path/to/file.txt', 'r')
La fonction open()
prend en compte plusieurs arguments. Nous nous concentrerons sur les deux premiers, le premier étant un paramètre positionnel de type chaîne de caractères représentant le chemin du fichier à ouvrir. Le deuxième paramètre facultatif est également une chaîne de caractères, qui spécifie le mode d’interaction que vous souhaitez pour l’objet fichier renvoyé par l’appel de fonction. Les modes les plus courants sont répertoriés dans le tableau ci-dessous, la valeur par défaut étant ‘r’ pour la lecture.
Mode | Description | |
---|---|---|
r |
Ouvrir pour lire du texte brut | |
w |
Ouvrir pour écrire du texte brut | |
a |
Ouvrir un fichier existant pour ajouter du texte brut | D’autres fichiers sont également disponibles. texte | rb |
Ouvrir pour lire des données binaires | wb |
Ouvrir pour écrire des données binaires |
Une fois que vous avez écrit ou lu toutes les données souhaitées pour un objet fichier, vous devez fermer le fichier afin que les ressources puissent être réallouées sur le système d’exploitation sur lequel le code est exécuté.
fp.close()
Vous verrez souvent de nombreux extraits de code sur Internet ou dans des programmes dans la nature qui ne ferment pas explicitement les objets fichiers qui ont été générés en accord avec l’exemple ci-dessus. C’est toujours une bonne pratique de fermer une ressource objet fichier, mais beaucoup d’entre nous sont soit trop paresseux ou oublieux pour le faire, soit pensent être intelligents parce que la documentation suggère qu’un objet fichier ouvert se fermera de lui-même une fois qu’un processus se terminera. Or, ce n’est pas toujours le cas.
Au lieu de rabâcher combien il est important de toujours appeler close()
sur un objet fichier, j’aimerais fournir une autre façon, plus élégante, d’ouvrir un objet fichier et de s’assurer que l’interprète Python nettoie après nous 🙂
with open('path/to/file.txt') as fp: # do stuff with fp
En utilisant simplement le mot-clé with
(introduit dans Python 2.5) pour envelopper notre code d’ouverture d’un objet fichier, les internes de Python feront quelque chose de similaire au code suivant pour s’assurer que, quoi qu’il arrive, l’objet fichier est fermé après utilisation.
try: fp = open('path/to/file.txt') # do stuff with fpfinally: fp.close()
L’une ou l’autre de ces deux méthodes convient, le premier exemple étant la manière la plus « pythonique ».
Lecture ligne par ligne
Maintenant, passons à la lecture effective d’un fichier. L’objet fichier renvoyé par open()
possède trois méthodes explicites courantes (read
readline
, et readlines
) pour lire les données et une autre manière implicite.
La méthode read
va lire toutes les données dans une seule chaîne de texte. C’est utile pour les petits fichiers où vous voudriez faire une manipulation de texte sur l’ensemble du fichier, ou tout ce qui vous convient. Ensuite, il y a readline
qui est une façon utile de ne lire que des incréments de lignes individuelles à la fois et de les retourner sous forme de chaînes de caractères. La dernière méthode explicite, readlines
, lira toutes les lignes d’un fichier et les retournera sous forme de liste de chaînes de caractères.
Comme mentionné précédemment, vous pouvez utiliser ces méthodes pour ne charger que de petits morceaux du fichier à la fois. Pour ce faire avec ces méthodes, vous pouvez leur passer un paramètre indiquant le nombre d’octets à charger à la fois. C’est le seul argument que ces méthodes acceptent.
Une implémentation pour lire un fichier texte une ligne à la fois est présentée ci-dessous, qui se fait via la méthode readline()
.
Note : Pour le reste de cet article, je vais démontrer comment lire dans le texte du livre L' » Iliade d’Homère « , qui peut être trouvé sur gutenberg.org, ainsi que dans le repo GitHub où se trouve le code de cet article.
Dans readline.py, vous trouverez le code suivant. Dans le terminal, si vous exécutez $ python readline.py
, vous pourrez voir le résultat de la lecture de toutes les lignes de l’Iliade, ainsi que leurs numéros de ligne.
Le bout de code ci-dessus ouvre un objet fichier stocké dans une variable appelée fp
, puis lit une ligne à la fois en appelant readline
sur cet objet fichier de manière itérative dans une boucle while
et l’imprime sur la console.
En exécutant ce code, vous devriez voir quelque chose comme ce qui suit :
$ python forlinein.py Line 0: BOOK ILine 1: Line 2: The quarrel between Agamemnon and Achilles--Achilles withdrawsLine 3: from the war, and sends his mother Thetis to ask Jove to helpLine 4: the Trojans--Scene between Jove and Juno on Olympus.Line 5: Line 6: Sing, O goddess, the anger of Achilles son of Peleus, that broughtLine 7: countless ills upon the Achaeans. Many a brave soul did it sendLine 8: hurrying down to Hades, and many a hero did it yield a prey to dogs andLine 9: vultures, for so were the counsels of Jove fulfilled from the day on...
Bien que cela soit parfaitement bien, il existe une dernière façon que j’ai mentionnée fugitivement plus tôt, qui est moins explicite mais un peu plus élégante, que je préfère de loin. Cette dernière façon de lire un fichier ligne par ligne comprend l’itération sur un objet fichier dans une boucle for
, assignant chaque ligne à une variable spéciale appelée line
. L’extrait de code ci-dessus peut être répliqué dans le code suivant, qui se trouve dans le script Python forlinein.py:
filepath = 'Iliad.txt'with open(filepath) as fp: for cnt, line in enumerate(fp): print("Line {}: {}".format(cnt, line))
Dans cette implémentation, nous profitons d’une fonctionnalité Python intégrée qui nous permet d’itérer sur l’objet fichier implicitement en utilisant une boucle for
en combinaison avec l’utilisation de l’objet itérable fp
. Non seulement cela est plus simple à lire, mais cela prend également moins de lignes de code à écrire, ce qui est toujours une meilleure pratique digne d’être suivie.
Une application d’exemple
Je m’en voudrais d’écrire une application sur la façon de consommer des informations dans un fichier texte sans démontrer au moins une utilisation triviale de la façon d’utiliser une telle compétence digne d’intérêt. Ceci étant dit, je vais démontrer une petite application qui se trouve dans wordcount.py, qui calcule la fréquence de chaque mot présent dans « L’Iliade d’Homère » utilisé dans les exemples précédents. Cela crée un simple sac de mots, qui est couramment utilisé dans les applications NLP.
Le code ci-dessus représente un script python en ligne de commande qui attend un chemin de fichier passé en argument. Le script utilise le module os
pour s’assurer que le chemin de fichier passé est un fichier qui existe sur le disque. Si le chemin existe alors chaque ligne du fichier est lue et passée à une fonction appelée record_word_cnt
comme une liste de chaînes de caractères, délimitées les espaces entre les mots ainsi qu’un dictionnaire appelé bag_of_words
. La fonction record_word_cnt
compte chaque instance de chaque mot et l’enregistre dans le dictionnaire bag_of_words
.
Une fois que toutes les lignes du fichier sont lues et enregistrées dans le dictionnaire bag_of_words
, alors un appel final à la fonction order_bag_of_words
est appelé, qui renvoie une liste de tuples au format (mot, nombre de mots), triés par nombre de mots. La liste de tuples retournée est utilisée pour imprimer les 10 mots les plus fréquents.
Conclusion
Donc, dans cet article, nous avons exploré les moyens de lire un fichier texte ligne par ligne de deux manières, dont une qui me semble un peu plus pythonique (ceci étant la deuxième manière démontrée dans forlinein.py). Pour conclure, j’ai présenté une application triviale qui est potentiellement utile pour lire et prétraiter des données qui pourraient être utilisées pour l’analyse de texte ou l’analyse de sentiment.
0 commentaire