Les fichiers

Une vidéo de présentation des fichiers…

Python peut traiter des fichiers texte et des fichiers binaires (images, sons, etc…). Pour ce cours, nous travaillerons exclusivement avec des fichiers contenant du texte. Nous utiliserons à titre d’exemple l’oeuvre de Corneille, Le Cid, contenue dans le fichier lecid.txt.

Ouverture du fichier

Ouvrir un fichier c’est établir la connexion avec la ressource contenant les données.

On ouvre un fichier avec la fonction open() qui peut ne nécessiter qu’un seul argument, le nom du fichier à ouvrir. Si aucune arborescence n’est précisée, le répertoire dans lequel le fichier est recherché est celui depuis lequel a été lancé l’interpréteur Python:

>>> f = open('lecid.txt')
>>> f
<_io.TextIOWrapper name='index.rst' mode='r' encoding='cp1252'>

Le mode d’ouverture par défaut du fichier est en lecture seule : mode='r' et l’encodage est celui du terminal depuis lequel a été lancé l’interpréteur Python : encoding='cp1252'. Ce sera cependant une bonne pratique que de préciser explicitement ces deux paramètres.

open() retourne un file-object de type io.TextIOWrapper. Cette classe hérite de io.TextIOBase et io.IOBase.

>>> type(f)
<class '_io.TextIOWrapper'>
>>> import io
>>> isinstance(f, io.TextIOBase)
True
>>> isinstance(f, io.IOBase)
True

L’objet retourné par open() dispose de plusieurs méthodes. Ici seules les plus importantes ont été conservées pour l’affichage:

>>> dir(f)
[..., 'close', ..., 'read', ..., 'readline', 'readlines', ..., 'write', 'writelines']

L’encodage utilisé est également disponible dans un attribut:

>>> f.encoding # interpréteur Python lancé depuis une console Windows
'cp1252'

Comme précisé plus haut, c’est cependant une bonne pratique de préciser explicitement l’encodage du fichier dans les paramètres de la fonction open(). C’est même indispensable lorsque le fichier comporte des caractères accentués.

>>> f = open('lecid.txt', mode='r', encoding='utf8')
>>> f.encoding
'utf8'

Le nom du fichier est accessible dans l’attribut name:

>>> f.name
'lecid.txt'

Fermeture du fichier

Fermer un fichier c’est rompre la connexion avec la ressource contenant les données, et donc libérer cette dernière pour le système d’exploitation.

La fonction close() permet de fermer le fichier une fois la lecture effectuée:

>>> f.closed
False
>>> f.close()
>>> f.closed
True

La bonne pratique de manipulation d’un fichier consiste donc en 3 étapes :

  1. ouvrir le fichier

  2. réaliser les opérations de lecture/écriture

  3. fermer le fichier

La construction with

L’action d’ouverture-fermeture d’un fichier est non seulement très courante mais la fermeture du fichier, après les opérations de lecture/écriture, nécessaire. La construction with est une façon concise, efficace et élégante de fermer le fichier après les opérations de lecture/écriture:

>>> with open('lecid.txt', mode='r', encoding='utf8') as f:
...     s = f.read()
...
>>> f.closed
True

Cette méthode est sure car le fichier est automatiquement fermé après l’exécution des instructions du bloc with.

with est un context manager. Il permet de définir des opérations à exécuter :

  • avant les instructions du bloc ;

  • après les instructions du bloc.

Note

with est utilisé ici avec un objet de type io.TextIOWrapper mais peut être employé avec tout objet implémentant les méthodes :

  • __enter__() ;

  • et __exit__().

Lecture du contenu

Il existe plusieurs façon de lire le contenu d’un fichier:

On peut récupérer l’intégralité du contenu dans une chaîne de caractères avec la méthode read() comme dans l’exemple ci dessus.

>>> s = f.read()
>>> type(s)
<class 'str'>
>>> len(s) # nombre de caractères
95302
>>> s[-46:]
'Laisse faire le temps, ta vaillance et ton roi'

Un autre appel à read() retourne la chaîne vide (car tout le fichier a été lu par l’instruction précédente):

>>> s = f.read()
>>> s
''

On peut aussi récupérer l’intégralité du contenu dans une liste de chaînes de caractères avec readlines()

>>> with open('lecid.txt', mode='r', encoding='utf8') as f:
...     l = f.readlines()
>>> type(l)
<class 'list'>
>>> len(l) # nombre de lignes
3236
>>> l[-1]
'Laisse faire le temps, ta vaillance et ton roi'
>>> for i in l[785:787]:
...     print(i, end='')
...
Je suis jeune, il est vrai ; mais aux âmes bien nées
La valeur n'attend point le nombre des années.

On peut également lire le fichier ligne par ligne avec readline():

>>> f.readline()
'LE CID\n'
>>> f.readline()
'======\n'
>>> f.readline()
'\n'

readline() n’a d’intérêt qu’encapsulé dans une boucle for ou while simple et que si la taille du fichier est trop importante pour un chargement total en mémoire. Sinon readlines() sera préférée:

>>> with open('lecid.txt', mode='r', encoding='utf8') as f:
...     for i in range(10):
...         print(f.readline())

Attention, la construction for ... in effectue un appel à readline(). On peut donc lire le fichier contenant les entiers consécutifs de 0 à 9 comme suit:

>>> with open('entiers.txt', mode='r', encoding='utf8') as f:
...     for l in f:
...         print(l)
0
1
2
3
4
5
6
7
8
9

Si on ajoute un autre appel à readline() dans la boucle en plus de celui effectué par la construction for ... in f:, la moitié des lignes ne sont plus affichées.

>>> with open('entiers.txt', mode='r', encoding='utf8') as f:
...     for l in f:
...         print(f.readline(), end='')
...
1
3
5
7
9

Note

Le parcours du fichier se fait ici en itérant sur un objet de type file-object, ce qui en fait un itérable au même titre que les containers et les chaînes de caractères.

Ecriture dans un fichier

On écrit dans un fichier avec la méthode write(). Il faut auparavant ouvrir le fichier en écriture (mode='w'):

>>> with open('file.txt', mode='w', encoding='utf8') as f:
...     f.write("M. Churchill, si j'étais votre femme, je mettrais du poison dans votre café !\n")
...     f.write("Lady Astor, si j'étais votre mari, je le boirais !")
...
78
50

La méthode write() retourne le nombre de caractères écrits dans le fichier.

On peut également utiliser la méthode writelines() qui permet d’écrire dans un fichier un ensemble de chaines de caractères stockées dans une liste.

Les fichiers csv

Le format csv Comma Separated Value est couramment utilisé pour échanger des données au format texte. Le module csv de Python dispose de méthodes spécifiques pour lire ce genre de format.

On considère le fichier des observations météo de la station d’Edimbourg en Ecosse Edinburgh_2015_Oct.csv.

Ouvrir ce fichier avec un éditeur de texte pour en observer la structure.

Pour en lire le contenu, Python utilise la fonction reader() qui retourne un itérable:

>>> with open('Edinburgh_2015_Oct.csv', 'r') as f:
...     r = csv.reader(f)
...     l = list(r) # l'itérable est converti en liste
...

Le format Comma Separated Value ne fixe pas le délimiteur utilisé pour séparer les données. Pour le format anglo-saxon, la virgule , est utilisée.

>>> r.dialect.delimiter
','

La taille de la liste construite à partir de l’objet retourné par reader() est égale au nombre de lignes du fichier:

>>> len(l)
44703

La première ligne contient l’en tête:

>>> l[0]
['date-time', 'atmospheric pressure (mBar)', 'rainfall (mm)', 'wind speed (m/s)', 'wind direction (degrees)', 'surface temperature (C)', 'relative humidity (%)', 'solar flux (Kw/m2)', 'battery (V)']

A partir de la seconde, on trouve les données:

>>> l[1] # la première ligne de données
['2015/10/01 00:01', '1035', '0', '0', '0', '9.28', '93.9', '0', '13.77']

A expérimenter…

On considère le fichier synop.2015110112.csv qui contient des données produites par Météo France au format csv.

Ouvrir ce fichier avec un éditeur de texte pour en observer la structure.

Le séparateur décimal français étant la virgule ,, cette dernière ne peut pas être utilisée comme délimiteur. La convention française est d’utiliser le point virgule ;. Il faut pour cela utiliser le paramètre delimiter de la fonction reader().

>>> with open('synop.2015110112.csv', 'r') as f:
...     r = csv.reader(f, delimiter=';')
...     l = list(r)

Combien de lignes comporte le fichier ?

Combien y a t-il de données par ligne ?

Note

Le travail avec les fichiers csv est facilité dans Visual Studio Code par l’extension Rainbow CSV. Elle s’installe à partir du menu Affichage > Extensions.

Ce qu’il faut retenir

  • est la fonction qui permet d’ouvrir un fichier

  • est la fonction qui permet de fermer un fichier

  • La fermeture de fichier est automatique si on utilise la construction

  • On peut ouvrir un fichier en ne précisant que son nom

  • Si on ne le précise pas le mode d’ouverture par défaut d’un fichier est en écriture

  • Lorsqu’on ouvre un fichier, c’est une bonne pratique de préciser son mode d’ouverture, lecture ou écriture

  • Si on ne le précise pas l’encodage par défaut lors de l’ouverture d’un fichier est celui du terminal

  • Lorsqu’on ouvre un fichier, c’est une bonne pratique de préciser son encodage

  • sont les 3 méthodes de lecture d’un fichier texte

  • La méthode read() retourne une chaine de caractères

  • La méthode readlines() retourne une liste de chaine de caractères

  • sont les 2 méthodes d’écriture dans un fichier texte

  • On peut itérer sur l’objet retourné par la fonction open()

  • Un fichier csv est un fichier texte

  • Un fichier csv ne peut être lu qu’avec le module csv

  • Le module csv facilite la lecture d’un fichier csv

  • La première ligne d’un fichier csv comporte des données

  • Le délimiteur d’un fichier csv est toujours le caractère ,

  • Le délimiteur d’un fichier csv est toujours le caractère ;

  • On peut préciser le délimiteur d’un fichier csv à la lecture