Aller au contenu

📑 Lire un fichier⚓︎

Le Projet Gutenberg est une bibliothèque en ligne regroupant les versions numériques d'ouvrages libres de droits. On y a récupéré le fichier des Fables de la Fontaine au format txt.

La fonction open⚓︎

Ouvrir un fichier avec Python est simple. On utilise la fonction open présente dans la bibliothèque native.

Cette fonction prend plusieurs paramètres. Retenons les trois suivants (déroulez pour avoir des détails):

file : le nom du fichier

Le nom du fichier (avec son extension donc, au format str).

Attention, par « nom » on désigne l'adresse du fichier. Cette adresse peut-être :

  • absolue, depuis la racine du disque, C:/home/nico/Documents/donnees_en_table/fables.txt par exemple ;

  • ou relative, depuis le fichier Python qui ouvre le fichier, fables.txt par exemple si les deux fichiers sont dans le même dossier.

On conseille très fortement d'utiliser des adresses relatives.

mode : le mode d'ouverture

Le mode d'ouverture du fichier (au format str).

On peut retenir les modes suivants :

Caractère Signification
'r' ouvre en lecture, en mode texte
'w' ouvre en écriture, en effaçant le contenu du fichier
'a' ouvre en écriture, en ajoutant les données à la fin du fichier
'b' mode binaire

On notera que le mode 'w' efface directement le contenu du fichier, il n'y a pas de message d'avertissement !

encoding : l'encodage utilisé

Le type d'encodage (au format str).

L'encodage d'un fichier correspond à la façon dont le programme qui l'ouvre doit interpréter les données qu'il contient.

Un fichier est stocké en machine sous forme d'une succession de bits. Dans la table ASCII initiale, 7 bits représentent un caractère. Dans la table ASCII étendue, il faut 8 bits pour représenter un caractère. L'encodage 'utf-8' est plus subtil : les caractères « courants » (l'alphabet latin par exemple) sont codés sur 8 bits, les caractères moins « courants » sur 16 voire 24 bits.

Changer l'encodage lors de l'ouverture d'un fichier ne modifie pas les données contenues dans le fichier mais la façon de les lire.

Par exemple les bits 010100110110100101101101011100000110110001100101001000000111010001100101011110000111010001100101 lus :

  • avec l'encodage 'utf-8' donnent 'Simple texte',

  • avec l'encodage 'utf-16 LE' donnent '楓灭敬琠硥整' !

L'encodage le plus classique pour nous sera 'utf-8'.

La fonction open peut être utilisée de deux façons :

  • utilisation classique, on ouvre et on ferme le fichier :

    🐍 Script Python
    fichier = open(file="fichier.txt", mode="r", encoding="utf-8")
    # Traitement du fichier
    fichier.close()
    

    Techniquement, on devrait même utiliser un try ... except au cas où le fichier est inaccessible :

    🐍 Script Python
    try:
        fichier = open(file="fichier.txt", mode="r", encoding="utf-8")
        # Traitement du fichier
        fichier.close()
    except IOError:  # Le fichier est inaccessible
        print("Le fichier est inaccessible")
    
  • utilisation avec with, il est inutile de fermer le fichier et de gérer les erreurs, c'est automatique :

    🐍 Script Python
    with open(file="fichier.txt", mode="r", encoding="utf-8") as fichier:
        # Traitement du fichier
    

On utilisera la seconde méthode.

Lire le fichier, des lignes, une ligne !⚓︎

Une fois le fichier ouvert, on peut réaliser différentes actions. Si l'objet renvoyé par open s'appelle fichier, on peut :

  • fichier.read() : lit la totalité du fichier. Renvoie une unique chaîne de caractères.
  • fichier.readlines() : lit la totalité du fichier ligne par ligne. Renvoie la liste contenant les différentes lignes.
  • fichier.readline() : lit la prochaine ligne du fichier ligne par ligne. Renvoie une chaîne de caractères.
Écrire ?

Si le fichier est ouvert en mode écriture, on peut écrire en faisant fichier.write("texte à écrire").

Attention toutefois à ne pas écraser le contenu du fichier !

Les deux scripts ci-dessous sont donc équivalents :

🐍 Script Python
with open(file="fichier.txt", mode="r", encoding="utf-8") as fichier:
    contenu = fichier.readlines()
🐍 Script Python
contenu = []
with open(file="fichier.txt", mode="r", encoding="utf-8") as fichier:
    for ligne in fichier:
        contenu.append(ligne)

La seconde permet toutefois de traiter précisément chaque ligne lue. On l'utilisera préférentiellement.

Des cigales et des fourmis⚓︎

Nous sommes donc équipés pour ouvrir et lire nos fichiers.

Lire les fables de la Fontaine

Le fichier contenant les fables de la Fontaine est nommé fables.txt, il est situé dans le même dossier que le fichier Python manipulé par l'éditeur. Il est encodé en utf-8.

Compléter le script afin d'ouvrir ce fichier et charger ses différentes lignes dans une liste.

###
# Testbksl-nlcontenupy-und = []bksl-nlwith open(file="fables.txt", mode="r", encoding="utf-8") as fichier:bksl-nl for ligne in fichier:bksl-nl contenupy-und.append(ligne)bksl-nlbksl-nlassert fables == contenupy-und, "Erreur de lecture"bksl-nl 5/5
#--- HDR ---#bksl-nlurlpy-undfichier = "fables.txt"bksl-nlencodage = "utf-8"bksl-nlbksl-nlfrom js import fetchbksl-nlbksl-nlreponse = await fetch(f"../{urlpy-undfichier}")bksl-nlcontenu = await reponse.text()bksl-nlbksl-nlwith open(file=urlpy-undfichier, mode="w", encoding=encodage) as fichier:bksl-nl fichier.write(contenu)bksl-nl#--- HDR ---#bksl-nlfables = []bksl-nlwith open(file=..., mode=..., encoding=...) as fichier:bksl-nl for ligne in ...:bksl-nl ....append(...)bksl-nlbksl-nlprint(fables[4:29]) # La cigale et la fourmibksl-nlbksl-nlfables = []bksl-nlwith open(file="fables.txt", mode="r", encoding="utf-8") as fichier:bksl-nl for ligne in fichier:bksl-nl fables.append(ligne)bksl-nlbksl-nl

A

Z

On obtient la liste suivante :

🐍 Script Python
fables = [
    'FABLES DE LA FONTAINE\n',
    '\n',
    'I\n',
    '\n',
    'LA CIGALE ET LA FOURMI.\n',
    '\n',
    '\n',
    'La cigale, ayant chanté\n',
    "Tout l'été,\n",
    ...
]

Le '\n' que l'on observe à plusieurs reprises est le caractère de retour à la ligne. On peut le supprimer en faisant ligne.strip(). En effet, la méthode strip supprime les caractères « blancs » au début ou à la fin d'une chaîne de caractères.

La lecture du fichier devient alors :

🐍 Script Python
fables = []
with open(file="fables.txt", mode="r", encoding="utf-8") as fichier:
    for ligne in fichier:
        ligne_propre = ligne.strip()  # suppression des \n
        fables.append(ligne_propre)

On obtient :

🐍 Script Python
fables = [
    'FABLES DE LA FONTAINE',
    '',
    'I',
    '',
    'LA CIGALE ET LA FOURMI.',
    '',
    '',
    'La cigale, ayant chanté',
    "Tout l'été,",
    ...
]
Relire les fables de la Fontaine

On a supprimé les caractères de retour à la ligne mais il reste désormais des lignes vides dans la liste fables.

Compléter le script afin d'ouvrir ce fichier, charger ses différentes lignes non vides dans une liste.

###
# Testbksl-nlcontenupy-und = []bksl-nlwith open(file="fables.txt", mode="r", encoding="utf-8") as fichier:bksl-nl for ligne in fichier:bksl-nl ligne = ligne.strip()bksl-nl if ligne:bksl-nl contenupy-und.append(ligne)bksl-nlbksl-nlassert fables == contenupy-und, "Erreur de lecture"bksl-nl 5/5
#--- HDR ---#bksl-nlurlpy-undfichier = "fables.txt"bksl-nlencodage = "utf-8"bksl-nlbksl-nlfrom js import fetchbksl-nlbksl-nlreponse = await fetch(f"../{urlpy-undfichier}")bksl-nlcontenu = await reponse.text()bksl-nlbksl-nlwith open(file=urlpy-undfichier, mode="w", encoding=encodage) as fichier:bksl-nl fichier.write(contenu)bksl-nl#--- HDR ---#bksl-nlfables = []bksl-nlbksl-nl# Compléter icibksl-nlbksl-nlprint(fables[2:25]) # La cigale et la fourmibksl-nlbksl-nlfables = []bksl-nlwith open(file="fables.txt", mode="r", encoding="utf-8") as fichier:bksl-nl for ligne in fichier:bksl-nl lignepy-undpropre = ligne.strip()bksl-nl if lignepy-undpropre != "":bksl-nl fables.append(lignepy-undpropre)bksl-nlbksl-nl

A

Z

Comptons les moutons⚓︎

Nous avons donc récupéré l'ensembles des fables dans une liste contenant toutes les lignes. Nous pouvons désormais faire des requêtes sur cette liste.

Combien de vers contiennent le mot "mouton" ? Pour le savoir on fait :

🐍 Script Python
moutons = [vers for vers in fables if "mouton" in vers.lower()]  # tous les vers contenant "mouton"
print(len(moutons))  # le nombre de vers

Astuce

On passe le vers en minuscule avec vers.lower() afin de trouver en une seule passe les chaînes "mouton", "Mouton", "MOUTON", etc

De même, on passe une chaîne de caractères mot en majuscule avec mot.upper().

Requêtes dans les fables

Compléter le script ci-dessous afin d'effectuer les requêtes demandées.

Toutes les recherches de chaînes de caractères seront insensibles à la casse (utiliser vers.lower() comme ci-dessus).

###
# listepy-und1 contient les vers dans lequel apparaît la chaîne "mouton"bksl-nlattendu = [vers for vers in fables if "mouton" in vers.lower()]bksl-nlassert listepy-und1 == attendu, "Erreur sur la liste 1"bksl-nlbksl-nl# listepy-und2 contient les vers dans lequel apparaît la chaîne "cigale"bksl-nlattendu = [vers for vers in fables if "cigale" in vers.lower()]bksl-nlassert listepy-und2 == attendu, "Erreur sur la liste 2"bksl-nlbksl-nl# listepy-und3 contient les vers dans lequel apparaîssent les chaînes "cigale" et "fourmi"bksl-nlattendu = [vers for vers in fables if "cigale" in vers.lower() and "fourmi" in vers.lower()]bksl-nlassert listepy-und3 == attendu, "Erreur sur la liste 3"bksl-nlbksl-nl# listepy-und4 contient les vers de plus de 5 caractères de long (inclus)bksl-nlattendu = [vers for vers in fables if len(vers) >= 5]bksl-nlassert listepy-und4 == attendu, "Erreur sur la liste 4"bksl-nlbksl-nl# listepy-und5 contient les vers dans lesquels on utilise une apostrophe (')bksl-nlattendu = [vers for vers in fables if "'" in vers]bksl-nlassert listepy-und5 == attendu, "Erreur sur la liste 5"bksl-nlbksl-nl# listepy-und6 contient les noms des fablesbksl-nl# (ils font plus de 6 caractères de long et sont en majuscule)bksl-nlattendu = [vers for vers in fables if len(vers) >= 6 and vers.upper() == vers]bksl-nlassert listepy-und6 == attendu, "Erreur sur la liste 6"bksl-nlbksl-nl 10/10
#--- HDR ---#bksl-nlurlpy-undfichier = "fables.txt"bksl-nlencodage = "utf-8"bksl-nlbksl-nlfrom js import fetchbksl-nlbksl-nlreponse = await fetch(f"../{urlpy-undfichier}")bksl-nlcontenu = await reponse.text()bksl-nlbksl-nlwith open(file=urlpy-undfichier, mode="w", encoding=encodage) as fichier:bksl-nl fichier.write(contenu)bksl-nl#--- HDR ---#bksl-nlfables = []bksl-nlwith open(file="fables.txt", mode="r", encoding="utf-8") as fichier:bksl-nl for ligne in fichier:bksl-nl lignepy-undpropre = ligne.strip()bksl-nl if lignepy-undpropre != "":bksl-nl fables.append(lignepy-undpropre)bksl-nlbksl-nl# listepy-und1 contient les vers dans lequel apparaît la chaîne "mouton"bksl-nllistepy-und1 = ...bksl-nlbksl-nl# listepy-und2 contient les vers dans lequel apparaît la chaîne "cigale"bksl-nllistepy-und2 = ...bksl-nlbksl-nl# listepy-und3 contient les vers dans lequel apparaîssent les chaînes "cigale" et "fourmi"bksl-nllistepy-und3 = ...bksl-nlbksl-nl# listepy-und4 contient les vers de plus de 5 caractères de long (inclus)bksl-nllistepy-und4 = ...bksl-nlbksl-nl# listepy-und5 contient les vers dans lesquels on utilise une apostrophe (')bksl-nllistepy-und5 = ...bksl-nlbksl-nl# listepy-und6 contient les noms des fablesbksl-nl# (ils font plus de 6 caractères de long et sont en majuscule)bksl-nllistepy-und6 = ...bksl-nlbksl-nl# listepy-und1 contient les vers dans lequel apparaît la chaîne "mouton"bksl-nllistepy-und1 = [vers for vers in fables if "mouton" in vers.lower()]bksl-nlbksl-nl# listepy-und2 contient les vers dans lequel apparaît la chaîne "cigale"bksl-nllistepy-und2 = [vers for vers in fables if "cigale" in vers.lower()]bksl-nlbksl-nl# listepy-und3 contient les vers dans lequel apparaîssent les chaînes "cigale" et "fourmi"bksl-nllistepy-und3 = [vers for vers in fables if "cigale" in vers.lower() and "fourmi" in vers.lower()]bksl-nlbksl-nl# listepy-und4 contient les vers de plus de 5 caractères de long (inclus)bksl-nllistepy-und4 = [vers for vers in fables if len(vers) >= 5]bksl-nlbksl-nl# listepy-und5 contient les vers dans lesquels on utilise une apostrophe (')bksl-nllistepy-und5 = [vers for vers in fables if "'" in vers]bksl-nlbksl-nl# listepy-und6 contient les noms des fablesbksl-nl# (ils font plus de 6 caractères de long et sont en majuscule)bksl-nllistepy-und6 = [vers for vers in fables if len(vers) >= 6 and vers.upper() == vers]bksl-nlbksl-nl

A

Z