Fichiers et exceptions en Python

Apprends à faire fonctionner des programmes Python avec des fichiers et à gérer les erreurs. Lis des fichiers texte en entier ou ligne par ligne, écris et ajoute du texte sans risque avec l’instruction with, et localise des fichiers avec des chemins relatifs et absolus et pathlib. Lis et écris des données CSV avec le module csv, notamment des lignes sous forme de dictionnaires. Ensuite, intercepte les erreurs attendues avec try et except, utilise else et finally, lève tes propres exceptions avec des messages clairs et construis des programmes qui signalent les fichiers manquants et les données invalides au lieu de planter.

DébutantUnité 8 sur 10 de la formation Formation : Python : variables, boucles, fonctions et fichiers

Ce que tu vas apprendre

  1. Ouvrir des fichiers texte, lire leur contenu de la manière adaptée à la tâche, écrire et ajouter du texte sans perdre de données, et traiter un fichier ligne par ligne pour rechercher, compter et filtrer.
    • Ouvrir un fichier texte et lire son contenu
      Utiliser open() pour relier un programme à un fichier texte, choisir la bonne façon de le lire et transformer le texte lu en données utilisables.
    • Fermer automatiquement les fichiers avec l’instruction with
      Utiliser with open(...) as f: pour fermer les fichiers au bon moment, même lorsqu’une erreur se produit.
    • Écrire et ajouter du texte dans des fichiers
      Choisir le bon mode pour créer, écraser ou compléter un fichier, et écrire du texte avec write() et print() afin que les lignes soient exactement conformes à ce qui est prévu.
    • Rechercher, compter et filtrer les lignes d’un fichier
      Traiter un fichier ligne par ligne pour trouver les lignes nécessaires, les compter ou en calculer le total, puis écrire les résultats dans un nouveau fichier.
  2. Indiquer à Python l’emplacement exact d’un fichier, comprendre pourquoi un programme ne trouve parfois pas un fichier qui existe et construire des chemins qui fonctionnent sous Windows, macOS et Linux.
    • Utiliser correctement les chemins relatifs et absolus
      Écrire des chemins absolus et relatifs, savoir à partir de quel dossier commence un chemin relatif et éviter les pièges des barres obliques inverses dans les chemins Windows.
    • Construire des chemins et gérer des dossiers avec pathlib
      Utiliser les objets Path du module pathlib pour assembler, examiner et vérifier des chemins, trouver des fichiers, créer des dossiers et lire ou écrire de petits fichiers en une étape.
  3. Utiliser le module csv de Python pour lire des données tabulaires dans des fichiers CSV, les convertir en nombres et écrire les résultats au format CSV pour qu’un tableur puisse les ouvrir.
    • Lire des données CSV avec csv.reader
      Comprendre comment un fichier CSV stocke un tableau, le lire ligne par ligne avec csv.reader, passer l’en-tête et convertir les valeurs nécessaires.
    • Écrire des fichiers CSV avec csv.writer
      Créer des fichiers CSV à partir de listes avec csv.writer, pour que les virgules, les guillemets et les fins de ligne soient correctement gérés.
    • Désigner les colonnes par leur nom avec DictReader et DictWriter
      Lire chaque ligne CSV comme un dictionnaire dont les clés proviennent de l’en-tête, filtrer et résumer les lignes par nom de colonne, puis écrire des dictionnaires au format CSV.
  4. Reconnaître les exceptions levées par Python, lire une trace d’appels pour en trouver la cause, intercepter les erreurs attendues et laisser un programme continuer ou l’arrêter avec un message clair au lieu de le laisser planter.
    • Reconnaître les exceptions courantes et lire une trace d’appels
      Savoir ce qu’est une exception, lire une trace d’appels de bas en haut et nommer les types d’exceptions courants ainsi que leurs causes habituelles.
    • Intercepter des exceptions avec try et except
      Écrire des blocs try et except qui interceptent les erreurs précises attendues, donnent un message utile à l’utilisateur et laissent apparaître les erreurs inattendues.
    • Utiliser else et finally, et suivre les exceptions à travers les fonctions
      Compléter une instruction try avec else et finally, prévoir l’ordre d’exécution de ses blocs et décider dans quelle fonction gérer une exception.
    • Assurer un échec maîtrisé des programmes qui traitent des fichiers et des données
      Combiner la gestion des fichiers et celle des exceptions pour que les fichiers manquants ou bloqués et les données invalides entraînent des messages clairs, des lignes ignorées ou un arrêt propre au lieu d’un plantage.
  5. Utiliser raise pour empêcher une fonction de continuer avec une entrée invalide, choisir des types d’exceptions et des messages adaptés, et laisser les erreurs se propager ou les transformer en erreurs plus claires.
    • Lever des exceptions pour rejeter des entrées invalides
      Utiliser l’instruction raise pour signaler qu’une fonction a reçu une valeur qu’elle ne peut pas traiter et laisser l’appelant décider de la réponse.
    • Relancer, chaîner et définir des exceptions personnalisées
      Laisser une exception se propager après y avoir réagi, transformer une erreur de bas niveau en une erreur plus claire et créer tes propres types d’exceptions pour les problèmes propres à ton programme.

Fichiers et exceptions en Python : cours

5 chapitres

1

Lire et écrire des fichiers texte

Les fichiers permettent à un programme de conserver des informations entre les exécutions et d’utiliser des données recueillies ailleurs. La lecture charge du texte en mémoire ; l’écriture enregistre des résultats pour la prochaine exécution ou pour une autre personne. Tu choisiras une méthode de lecture, contrôleras précisément ce qui est écrit et utiliseras l’indentation pour ne garder les fichiers ouverts que le temps nécessaire. Des exemples ligne par ligne combineront ensuite opérations sur les chaînes, décisions et compteurs pour transformer du texte brut en résultats utiles.

1.1 Lire du texte dans un programme

Un fichier texte conserve des informations après l’arrêt d’un programme. Python utilise un objet fichier, renvoyé par open(), pour manipuler ces informations. L’ouverture établit la connexion avec le fichier ; une opération de lecture récupère son texte.

Choisir ce qu’il faut lire

Le mode par défaut est "r", pour la lecture. Un nom seul est recherché dans le répertoire de travail courant. Si le fichier y est absent, open() lève FileNotFoundError.

with open("fruit.txt", encoding="utf-8") as f:
    text = f.read()

Supposons que le fichier contienne trois lignes, « apple », « banana » et « cherry », toutes avec une fin de ligne. text vaut 'apple\nbanana\ncherry\n'. La séquence d’échappement \n représente un seul caractère de saut de ligne. Une dernière ligne peut aussi se terminer sans saut de ligne.

OpérationRésultatUtile lorsque
f.read()Tout le texte restant dans une seule chaîneTu as besoin d’un petit fichier en entier
f.readline()La ligne suivante sous forme de chaîneTu as besoin d’une ligne maintenant
f.readlines()Toutes les lignes restantes sous forme de listeTu dois réutiliser les lignes
for line in f:Une ligne par passageTu peux traiter les lignes dans l’ordre

readline() renvoie '' à la fin du fichier. Une ligne vide qui possède une fin de ligne renvoie '\n' : une ligne vide et la fin du fichier sont donc deux choses différentes.

Suivre la position

La lecture fait avancer la position dans le fichier. Après que f.read() a lu tout le fichier, un autre appel renvoie '' ; une boucle sur ce même objet n’a plus rien à parcourir. Rouvre le fichier pour recommencer ou conserve le texte ou les lignes nécessaires dans une variable. read() et readlines() chargent le reste du fichier en mémoire. Parcourir directement le fichier permet de traiter un gros fichier ligne par ligne.

Les lignes conservent leurs caractères de saut de ligne. print(line) ajoute son propre saut de ligne, ce qui peut laisser des lignes vides supplémentaires à l’écran. Utilise print(line, end="") pour conserver l’espacement d’origine, ou supprime la fin de ligne avant l’affichage. line.rstrip("\n") supprime les sauts de ligne finaux ; line.strip() supprime aussi les espaces aux deux extrémités.

Transformer du texte en nombres

Même les chiffres arrivent sous forme de chaînes. Ce fichier contient les notes « 72 », « 85 » et « 90 » :

scores = []
with open("scores.txt", encoding="utf-8") as f:
    for line in f:
        scores.append(int(line))
total = sum(scores)
print(total, round(total / len(scores), 2))

La liste est [72, 85, 90], donc le programme affiche 247 82.33. int() accepte les espaces et les sauts de ligne qui entourent les chiffres. Une chaîne vide ou un mot tel que "forty" lève ValueError.

Lire les caractères avec le bon encodage

Un encodage associe les caractères aux octets stockés. UTF-8 peut représenter des caractères tels que « é » et les émojis. Utilise explicitement encoding="utf-8" pour les fichiers UTF-8. Python 3.15 active le mode UTF-8 par défaut ; les installations plus anciennes peuvent utiliser un encodage local. Un encodage incorrect peut produire un texte déformé ou une UnicodeDecodeError. Indiquer explicitement l’encodage ne convertit pas en UTF-8 un fichier enregistré dans un autre encodage.

Le bloc with ferme le fichier lorsqu’il se termine. Un fichier fermé ne peut pas être lu : un nouvel appel à f.read() lève ValueError.

Points clés

  • open() renvoie un objet fichier ; la lecture récupère le texte à partir de sa position courante.
  • Choisis une chaîne, une liste de lignes ou une boucle ligne par ligne selon la tâche.
  • La fin du fichier donne '' ; une ligne vide peut donner '\n'.
  • Convertis le texte numérique avec int() ou float() avant de calculer.
  • Utilise l’encodage correspondant au fichier et ferme celui-ci une fois terminé.

1.2 Des fichiers qui se ferment à la fin du bloc

Un fichier ouvert utilise des ressources du système d’exploitation. Le texte en cours d’écriture peut aussi attendre dans un tampon en mémoire avant d’atteindre le fichier. La fermeture libère les ressources et vide le tampon d’écriture. Une instruction with organise ce nettoyage à un endroit clair du code.

Lire dans le bloc, utiliser le résultat ensuite
with open("notes.txt", encoding="utf-8") as f:
    text = f.read()
print(len(text))

Les deux-points commencent le bloc. La ligne indentée s’exécute pendant que f est ouvert. Lorsque l’exécution atteint le print() non indenté, le fichier est fermé, mais text reste une chaîne ordinaire. Le nom f désigne toujours l’objet fichier ; f.closed vaut maintenant True.

Le même schéma fonctionne pour une liste :

with open("fruit.txt", encoding="utf-8") as f:
    lines = f.readlines()
for line in lines:
    print(line.strip().upper())

La boucle utilise les données déjà lues dans lines. Déplacer f.readlines() hors du bloc tenterait de lire un fichier fermé et lèverait ValueError.

Nettoyer lorsque l’exécution change de direction

Considère une fonction qui renvoie la première ligne :

def first_line(path):
    with open(path, encoding="utf-8") as f:
        return f.readline().rstrip("\n")

La valeur de retour est préparée dans le bloc. Python quitte ensuite le bloc et ferme le fichier avant que l’appelant reçoive cette valeur. Le fichier se ferme aussi lorsqu’une exception quitte le bloc. Un f.close() manuel placé après une instruction qui échoue ne serait jamais atteint.

Les objets fichier permettent ce comportement parce qu’ils sont des gestionnaires de contexte : des objets qui organisent la mise en place et le nettoyage autour d’un bloc with. Tu peux utiliser ce comportement sans écrire toi-même un gestionnaire de contexte.

Ouvrir ensemble un fichier d’entrée et un fichier de sortie
with open("in.txt", encoding="utf-8") as src, open("out.txt", "w", encoding="utf-8") as dst:
    for line in src:
        dst.write(line.upper())

Chaque ligne d’entrée est convertie en majuscules et écrite dans le fichier de sortie. Les deux fichiers se ferment à la fin du bloc. Si la seconde ouverture échoue, le premier fichier, déjà pris en charge par with, est fermé lorsque Python quitte l’instruction.

Le nettoyage et la gestion des erreurs ont des rôles différents

with n’intercepte pas les erreurs de fichier. Si open() ne trouve pas notes.txt, il lève FileNotFoundError avant l’exécution du corps. Si la conversion d’une ligne avec int() échoue dans le corps, le fichier se ferme et l’exception poursuit sa propagation. Une clause except correspondante est nécessaire pour reprendre le traitement ou afficher un message.

L’absence des deux-points à la fin de la ligne with provoque une SyntaxError.

Points clés

  • with ferme un fichier ouvert à la sortie normale, lors d’un retour et lorsqu’une exception fait quitter le bloc.
  • Les chaînes et les listes stockées restent utilisables après la fermeture du fichier.
  • L’indentation délimite la période pendant laquelle le fichier est ouvert.
  • Le nettoyage n’intercepte pas une exception ; sa gestion nécessite try et except.

1.3 Créer, remplacer et ajouter du texte

L’écriture commence par un choix concernant les données existantes. Le mode détermine si Python lit, remplace, complète ou crée un fichier. Fais ce choix avant d’appeler open(), car le remplacement est immédiat.

Choisir le mode
ModeFichier existantFichier manquant
"r"L’ouvre en lectureLève FileNotFoundError
"w"Le vide, puis l’ouvre en écritureLe crée
"a"Ajoute la sortie à la finLe crée
"x"Lève FileExistsErrorLe crée

Ouvrir l’unique copie de données importantes avec "w" détruit son ancien contenu, même si aucun write() ne suit. Utilise un fichier de sortie distinct pendant que tu apprends à transformer des données. "x" est utile lorsqu’il faut refuser le remplacement d’un fichier existant.

Ajouter "b", comme dans "rb", sélectionne le mode binaire pour les octets bruts. Les modes texte utilisent des chaînes et un encodage ; les modes binaires n’acceptent pas d’argument encoding.

Décider où les lignes se terminent
with open("todo.txt", "w", encoding="utf-8") as f:
    f.write("buy milk\n")
    f.write("call Sam\n")

Le fichier contient les deux lignes « buy milk » et « call Sam ». write() ajoute exactement la chaîne fournie, sans séparateur automatique. Sans les sauts de ligne, le fichier contiendrait "buy milkcall Sam" sur une seule ligne.

write() renvoie le nombre de caractères écrits. Par exemple, f.write("Ana,92\n") renvoie 7. C’est un nombre de caractères, qui ne correspond pas nécessairement au nombre d’octets encodés sur le disque. La méthode accepte une chaîne ; f.write(42) lève TypeError. Convertis d’abord un nombre, par exemple avec f.write(f"{score}\n").

Comparer les outils d’écriture

print() peut écrire dans un fichier :

with open("total.txt", "w", encoding="utf-8") as f:
    print("Total:", 247, file=f)

Le texte écrit est "Total: 247\n". print() convertit ses arguments, les sépare par des espaces et ajoute par défaut un saut de ligne final.

writelines() prend une séquence de chaînes, mais n’insère aucune fin de ligne. f.writelines(["a", "b"]) écrit "ab". Pour obtenir un élément par ligne, inclus un saut de ligne dans chaque chaîne ou assemble les chaînes avec "\n" et ajoute un saut de ligne final.

Conserver les exécutions précédentes
with open("log.txt", "a", encoding="utf-8") as f:
    f.write("Program started\n")

En partant sans fichier, deux exécutions produisent deux lignes. Avec "w", chaque exécution remplacerait l’entrée précédente. Le mode ajout ne fournit pas de saut de ligne manquant : si le texte existant se termine au milieu d’une ligne, le nouveau texte commence immédiatement après.

Pour un rapport, parcours des paires telles que [("Ana", 92), ("Ben", 78)] et écris f"{name}: {score}\n". La mise en forme a lieu avant l’écriture : f"{82.333:.1f}" produit donc le texte "82.3". with ferme ensuite le fichier de sortie et vide le tampon de texte à la fin du bloc.

Points clés

  • "w" vide un fichier existant dès son ouverture.
  • "a" ajoute à la fin ; "x" refuse de remplacer un fichier existant.
  • write() prend une chaîne et n’ajoute pas de saut de ligne.
  • print(..., file=f) convertit les valeurs et ajoute par défaut un saut de ligne.
  • writelines() écrit les chaînes à la suite sans ajouter de séparateurs.
  • Les modes binaires lisent ou écrivent des octets et n’acceptent pas d’argument d’encodage.

1.4 Trouver et enregistrer les lignes utiles

De nombreuses tâches sur les fichiers consistent en une boucle contenant une décision. Lis une ligne, supprime les espaces indésirables, décide si elle t’intéresse et mets à jour un résultat. Séparer ces étapes rend le programme plus facile à vérifier.

Parcourir un journal

Supposons que server.log contienne ces enregistrements, avec une ligne vide avant le dernier :

2026-03-01 08:14 INFO Server started
2026-03-01 08:20 ERROR Disk almost full
2026-03-01 09:02 INFO User login: maya
2026-03-01 09:15 WARNING Slow response
2026-03-01 10:40 ERROR Database timeout

2026-03-01 11:05 INFO Backup finished

Chaque enregistrement non vide comporte une date, une heure, un niveau et un message. Découpe seulement trois fois pour garder le message d’un seul tenant :

errors = 0
with open("server.log", encoding="utf-8") as f:
    for line in f:
        line = line.strip()
        if not line:
            continue
        parts = line.split(maxsplit=3)
        if parts[2] == "ERROR":
            errors += 1
            print(parts[3])
print(errors, "errors")

Pour le deuxième enregistrement, parts[2] vaut "ERROR" et parts[3] vaut "Disk almost full". Ce message s’affiche et le compteur passe à 1. L’erreur suivante le fait passer à 2. Le programme affiche les deux messages, puis « 2 errors ».

Rechercher dans la partie voulue
TestCe qu’il vérifie
line.startswith("From:")La ligne commence-t-elle par ce texte ?
"ERROR" in lineCe texte apparaît-il quelque part ?
line.find("ERROR")Où se trouve sa première occurrence, ou le résultat est-il -1 ?
parts[2] == "ERROR"Ce champ précis correspond-il exactement au niveau d’erreur ?

Une recherche n’importe où trouverait aussi « INFO No ERRORS today ». Vérifier le champ du niveau répond plus précisément à la question posée sur le journal.

Après strip(), une ligne vide vaut "" ; son découpage donne []. Accéder alors à parts[2] lèverait IndexError. L’instruction continue passe cette ligne avant tout accès par indice. Un enregistrement non vide mais incomplet nécessite aussi une vérification de sa longueur lorsque de tels enregistrements sont possibles.

Compter les catégories ou écrire un fichier filtré

Un dictionnaire conserve un compteur par niveau. Pour chaque enregistrement, affecte level = parts[2], puis exécute counts[level] = counts.get(level, 0) + 1. Pour le journal ci-dessus, les comptes sont {'INFO': 3, 'ERROR': 2, 'WARNING': 1}. La valeur par défaut 0 initialise une catégorie lors de sa première apparition.

Pour enregistrer les enregistrements correspondants, ouvre un fichier de destination distinct dans la même instruction with et écris une ligne lorsque son niveau correspond. Conserve la line d’origine si les espaces comptent ; si tu écris du texte nettoyé, rétablis son saut de ligne. N’ouvre jamais la source elle-même avec "w" : elle serait vidée avant le début de la lecture.

Voir les caractères invisibles

print(repr(line)) rend visibles les espaces finaux et les sauts de ligne, par exemple 'Disk full \n'. strip() supprime les deux, tandis que rstrip("\n") conserve les espaces. La lecture normale en mode texte transforme les fins de ligne Windows, Unix et ancien Mac reconnues en "\n". Une dernière ligne sans fin de ligne reste sans fin de ligne. Un nom de fichier recueilli avec input("File name: ").strip() permet à la même boucle de fonctionner avec différents fichiers d’entrée.

Points clés

  • Nettoie, sélectionne, traite et présente les résultats en étapes distinctes.
  • Passe les lignes vides avant d’accéder par indice aux champs obtenus par découpage.
  • Vérifie le champ voulu lorsqu’une recherche sur toute la ligne pourrait trouver trop de correspondances.
  • Utilise un dictionnaire pour conserver un compteur par catégorie.
  • Écris le résultat filtré dans un fichier différent.
  • repr() révèle les espaces et les caractères de saut de ligne cachés lors d’un affichage normal.
2

Localiser des fichiers avec des chemins

Un nom de fichier correct ne suffit pas à préciser son emplacement. Le dossier depuis lequel un programme démarre influe sur les chemins relatifs et peut être différent de celui qui contient le script. Tu suivras des chemins dans une arborescence, éviteras les séquences d’échappement dans les chaînes de chemins Windows et construiras des emplacements avec pathlib. Ces compétences aident à comprendre les erreurs de fichier manquant et permettent à un même projet de trouver ses données et de préparer ses dossiers de sortie sur différents ordinateurs.

2.1 Où Python cherche un fichier

Un chemin décrit un emplacement dans une arborescence de dossiers. Il peut commencer à la racine de cette arborescence ou au répertoire de travail courant du programme. Un fichier peut exister sur l’ordinateur tout en étant absent à l’emplacement demandé par ton programme.

Lire un chemin à partir de son point de départ
TypeExemplePoint de départ
Absolu, macOS ou Linux/Users/maya/data/notes.txtLa racine /
Absolu, WindowsC:/Users/Maya/data/notes.txtLa racine du lecteur C
Relatifdata/notes.txtRépertoire de travail courant

Supposons qu’un dossier nommé project contienne un dossier scripts et un dossier data. Tu exécutes python scripts/report.py depuis project. L’ouverture de "data/notes.txt" cherche dans project/data, même si le script se trouve dans project/scripts.

Si tu lances le même script depuis project/scripts, ce chemin relatif pointe alors vers l’intérieur de project/scripts/data. Le script n’a pas bougé ; le point de départ a changé.

from pathlib import Path
print(Path.cwd())

Ce code affiche le répertoire de travail courant. os.getcwd() après import os fournit la même information sous forme de chaîne. Les éditeurs et les outils de lancement peuvent choisir un répertoire de travail : examine-le donc lorsque l’emplacement n’est pas clair.

Parcourir les dossiers

Dans un chemin relatif, . désigne le dossier courant et .. son parent. Depuis project/scripts, ../data/notes.txt remonte à project, puis descend dans data. Ajouter .. sans vérifier le dossier de départ peut envoyer un programme au mauvais endroit.

Un chemin absolu est utile pour désigner un emplacement précis, mais un chemin tel que C:/Users/Maya/Desktop/data.csv lie le code partagé aux dossiers d’une seule personne. Utilise un chemin relatif avec un point de départ clair, ou construis-le à partir du dossier du script lorsque c’est là que se trouvent les données.

Conserver les barres obliques inverses de Windows

Windows affiche généralement des barres obliques inverses entre les dossiers. Dans une chaîne Python ordinaire, une barre oblique inverse commence une séquence d’échappement : \n devient un saut de ligne et \t une tabulation. Le littéral "C:\new\table.txt" ne contient donc pas le chemin souhaité.

Ces formes conservent le chemin voulu :

raw = r"C:\new\table.txt"
escaped = "C:\\new\\table.txt"
forward = "C:/new/table.txt"

Python sous Windows accepte les barres obliques. Une chaîne brute empêche les barres obliques inverses de devenir des séquences d’échappement, mais elle ne peut pas se terminer par une seule barre oblique inverse. Par exemple, r"C:\data\" est une syntaxe invalide.

Vérifier le nom autant que le dossier

Cherche les différences d’orthographe et les extensions masquées : un fichier affiché sous le nom « notes.txt » peut en réalité s’appeler « notes.txt.txt ». La casse compte aussi. Linux distingue généralement Data.csv de data.csv ; les configurations habituelles de Windows et de macOS ne les distinguent pas. Respecter la casse réelle permet au projet de rester utilisable sur différents systèmes.

Points clés

  • Les chemins relatifs partent du répertoire de travail courant.
  • Le répertoire de travail peut être différent du dossier du script.
  • . reste dans le dossier courant ; .. remonte à son parent.
  • Pour les chemins Windows, utilise des chaînes brutes, des barres obliques inverses doublées ou des barres obliques.
  • Vérifie les noms exacts, les extensions et la casse lorsqu’un fichier est introuvable.

2.2 Construire des chemins avec pathlib

Le module standard pathlib donne au chemin son propre objet. Un objet Path permet d’assembler des noms de dossiers, d’examiner un nom de fichier et d’effectuer des tâches courantes sur les fichiers sans construire manuellement des chaînes de séparateurs.

Assembler et examiner
from pathlib import Path
p = Path("reports") / "2026" / "sales.csv"
print(p.name)
print(p.stem)
print(p.suffix)
print(p.parent)

Les trois premiers résultats sont « sales.csv », « sales » et « .csv ». Le parent est le chemin reports/2026, affiché avec le séparateur du système. Ici, / assemble des parties de chemin ; il ne divise pas des nombres. L’ancienne fonction os.path.join() assemble aussi des parties de chemin sous forme de chaînes.

Un objet Path décrit un emplacement même avant que quoi que ce soit y existe. p.exists() vérifie si quelque chose existe à cet emplacement. p.is_file() et p.is_dir() distinguent un fichier d’un répertoire. Une vérification de l’existence ne peut pas garantir une ouverture ultérieure : le fichier peut disparaître ou les droits d’accès peuvent changer entre les deux opérations. Gère les erreurs d’ouverture lorsque le programme doit pouvoir reprendre le traitement.

Lire ou écrire un petit fichier

open() accepte directement un objet Path. Pour un petit fichier, ces méthodes gèrent aussi l’ouverture et la fermeture :

p = Path("greeting.txt")
p.write_text("Hello\n", encoding="utf-8")
text = p.read_text(encoding="utf-8")

text devient "Hello\n". write_text() remplace le contenu existant, comme une ouverture avec "w" ; cette méthode ne sert pas à ajouter du texte. read_text() charge tout le fichier : utilise donc une boucle sur le fichier lorsque tu dois traiter un gros fichier ligne par ligne.

Partir du dossier du script

Un fichier de données fourni à côté d’un script doit être localisé à partir de ce script, indépendamment du répertoire de travail :

base = Path(__file__).resolve().parent
scores_path = base / "data" / "scores.txt"
with open(scores_path, encoding="utf-8") as f:
    scores = f.readlines()

__file__ désigne le fichier du script. resolve() rend son chemin absolu et parent sélectionne le dossier qui le contient. Dans une console interactive, __file__ n’est pas défini : ce schéma s’utilise donc dans un script.

Trouver des fichiers et préparer des dossiers de sortie
for p in sorted(Path("logs").glob("*.txt")):
    text = p.read_text(encoding="utf-8")
    print(p.name, len(text.splitlines()))

glob("*.txt") sélectionne les chemins correspondants dans logs. iterdir() produit les entrées du dossier sans ce filtre par motif. Le tri rend l’ordre prévisible. splitlines() compte les lignes de texte sans traiter la fin de ligne finale comme une ligne vide supplémentaire.

L’écriture crée un fichier, mais pas les dossiers parents manquants. Prépare-les d’abord :

folder = Path("output") / "daily"
folder.mkdir(parents=True, exist_ok=True)
(folder / "report.txt").write_text("Ready\n", encoding="utf-8")

parents=True crée les dossiers manquants au-dessus de daily. exist_ok=True accepte un répertoire déjà existant. Cela ne transforme pas un fichier ordinaire existant en dossier.

Points clés

  • Path assemble les parties avec / et fonctionne directement avec open().
  • name, stem, suffix et parent donnent accès à différentes parties du chemin.
  • Vérifier l’existence d’un fichier ne peut pas garantir la réussite d’une ouverture ultérieure.
  • read_text() lit tout le texte ; write_text() le remplace.
  • Construis le chemin à partir de Path(__file__).resolve().parent pour les données situées par rapport au script.
  • Utilise glob() pour trouver des correspondances et mkdir() pour créer les dossiers manquants.
3

Lire et écrire des fichiers CSV

Les données tabulaires ont besoin de plus de structure qu’un ensemble de lignes. Un nom peut contenir une virgule, un champ peut contenir un saut de ligne et une quantité arrive toujours sous forme de texte. Tu utiliseras le module CSV pour préserver ces limites, convertir les valeurs nécessaires aux calculs et écrire des résultats qu’un autre programme peut lire. Les colonnes nommées rendent le traitement plus clair, tandis que les vérifications des en-têtes et de la structure des lignes aident à repérer les données incomplètes.

3.1 Lire les lignes et les champs CSV

Un fichier CSV stocke un tableau sous forme de texte. Ses enregistrements sont des lignes et ses champs sont des valeurs de colonnes. Les virgules séparent généralement les champs, mais les champs entre guillemets peuvent contenir des virgules et même des sauts de ligne. Utilise le module csv pour garder ces valeurs ensemble.

Laisser un objet reader gérer les guillemets
name,quiz1,quiz2
Ana,8,9
Ben,7,6
"Lopez, Maria",10,8

La première ligne est un en-tête qui contient les noms des colonnes. La dernière ligne de données comporte trois champs, et non quatre : la virgule dans le nom entre guillemets fait partie du nom. Un guillemet double à l’intérieur d’un champ entre guillemets est écrit deux fois. Découper chaque ligne avec split(",") ignorerait ces règles et couperait le nom en morceaux.

import csv
with open("grades.csv", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    header = next(reader)
    for row in reader:
        average = (int(row[1]) + int(row[2])) / 2
        print(row[0], average)

L’objet reader renvoie des listes de chaînes. next(reader) consomme l’en-tête une fois, laissant la boucle traiter les données. Le programme affiche « Ana 8.5 », « Ben 6.5 » et « Lopez, Maria 9.0 ». Dans la première ligne de données, la conversion de "8" et "9" donne un total de 17, puis la division par 2 donne 8,5.

Coordonner la gestion du fichier et l’analyse du tableau

Ouvre les fichiers CSV avec newline="" afin que le module csv gère lui-même les fins de ligne. C’est important lorsqu’un champ entre guillemets contient un saut de ligne. Un enregistrement CSV peut s’étendre sur plusieurs lignes physiques du fichier : un découpage ligne par ligne ne remplace donc pas un objet reader CSV.

Par défaut, l’objet reader laisse les valeurs sous forme de chaînes. Sans conversion, l’addition row[1] + row[2] assemble "8" et "9" en "89". Oublier de passer l’en-tête conduit plutôt à essayer de convertir "quiz1" et lève ValueError.

Si un fichier risque d’être vide, next(reader, None) consomme l’en-tête s’il est présent et renvoie None sinon. Une ligne CSV complètement vide devient []. Passe ces lignes avec if not row: continue avant tout accès par indice. Une ligne non vide contenant trop peu de champs nécessite aussi une vérification de sa longueur ; passer uniquement les lignes vides ne protège pas row[2] contre tous les enregistrements trop courts.

S’adapter au format du fichier
reader = csv.reader(f, delimiter=";", skipinitialspace=True)

Ce code choisit les points-virgules comme séparateurs et supprime les espaces qui les suivent immédiatement. Choisis le séparateur réellement utilisé par le fichier ; changer le séparateur ne transforme pas les virgules décimales en points décimaux. float("2,50") lève toujours ValueError.

Certains fichiers exportés par des tableurs commencent par un indicateur d’ordre des octets UTF-8. Les lire avec encoding="utf-8" peut laisser "\ufeff" au début du premier champ et transformer l’en-tête "name" en "\ufeffname". Pour ce format, encoding="utf-8-sig" supprime le marqueur ; cet encodage peut aussi lire les fichiers UTF-8 qui n’en contiennent pas.

Points clés

  • Un enregistrement CSV peut contenir des virgules ou des sauts de ligne entre guillemets.
  • Utilise csv.reader, et non un simple découpage sur les virgules, pour respecter la mise entre guillemets.
  • Ouvre les fichiers CSV avec newline="" et un encodage adapté.
  • Par défaut, l’objet reader renvoie des chaînes ; passe l’en-tête avant la conversion numérique.
  • Vérifie les lignes vides ou trop courtes avant d’accéder aux champs.
  • Choisis le bon délimiteur et prends en compte l’indicateur d’ordre des octets lorsqu’il est présent.

3.2 Écrire des lignes de tableau au format CSV

Un objet writer CSV transforme les valeurs en champs correctement séparés et mis entre guillemets. Fournis-lui des lignes sous forme de séquences de valeurs et laisse-le gérer la ponctuation. Cela évite une sortie qui semble correcte jusqu’à ce qu’un nom ou un message contienne une virgule.

Écrire un en-tête et des données
import csv
with open("summary.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["name", "average"])
    writer.writerow(["Ana", 8.5])
    writer.writerow(["Lopez, Maria", 9.0])

Le fichier contient les lignes name,average, Ana,8.5 et "Lopez, Maria",9.0. L’objet writer convertit les nombres en texte. Il met entre guillemets le nom contenant une virgule et double tout guillemet double à l’intérieur d’un champ entre guillemets. None devient un champ vide : relire le fichier ne permet donc pas de retrouver automatiquement None.

writerow() prend une ligne. writerows() prend une séquence de lignes, par exemple [["Ana", 8.5], ["Ben", 6.5]]. Passer directement "Ana" à writerow() lui donne en revanche trois caractères et produit A,n,a. Utilise ["Ana"] pour une ligne à un champ.

Confier les fins de ligne au module CSV

Utilise newline="" à l’ouverture du fichier de sortie. Par défaut, l’objet writer termine les enregistrements par "\r\n". Autoriser aussi la conversion des sauts de ligne en mode texte peut ajouter un retour chariot supplémentaire sous Windows et produire des lignes vides indésirables dans certains lecteurs. L’argument newline empêche cette seconde conversion.

Transformer un fichier en un autre
with open("grades.csv", newline="", encoding="utf-8") as src, open("summary.csv", "w", newline="", encoding="utf-8") as dst:
    reader = csv.reader(src)
    writer = csv.writer(dst)
    next(reader)
    writer.writerow(["name", "average"])
    for row in reader:
        average = (int(row[1]) + int(row[2])) / 2
        writer.writerow([row[0], round(average, 2)])

Pour les lignes de notes « Ana,8,9 », « Ben,7,6 » et "Lopez, Maria",10,8, les moyennes sont de 8,5, 6,5 et 9,0. L’objet reader retire les guillemets CSV de la valeur du champ en entrée ; l’objet writer les ajoute de nouveau au besoin en sortie. round() contrôle la valeur numérique écrite, mais n’impose pas l’affichage de deux décimales. Utilise un format tel que f"{average:.2f}" lorsque tu veux exactement deux décimales.

Ajouter sans répéter l’en-tête

Avant d’ouvrir un fichier en mode ajout, vérifie s’il a besoin d’un en-tête :

from pathlib import Path
p = Path("sales.csv")
needs_header = not p.exists() or p.stat().st_size == 0
with open(p, "a", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    if needs_header:
        writer.writerow(["item", "quantity"])
    writer.writerow(["coffee", 4])

Un fichier existant mais vide a lui aussi besoin de son en-tête. Écrire l’en-tête à chaque exécution place les noms des colonnes au milieu des données. Ce schéma suppose qu’un seul programme met le fichier à jour ; vérifier son existence ne le protège pas contre les modifications par d’autres programmes.

Points clés

  • Passe une séquence de champs à writerow() et des lignes à writerows().
  • L’objet writer convertit les valeurs et gère la mise entre guillemets ; None devient un champ vide.
  • Utilise newline="" aussi bien pour écrire que pour lire du CSV.
  • N’ajoute un en-tête que lorsque le fichier est nouveau ou vide.

3.3 Utiliser les noms de colonnes dans le code CSV

Un code fondé sur les positions, comme row[2], dépend de l’ordre des colonnes. Un objet reader fondé sur les dictionnaires permet de désigner par son nom la valeur nécessaire. Un dictionnaire associe des clés à des valeurs ; ici, l’en-tête fournit les clés et chaque enregistrement de données fournit leurs valeurs.

Lire les champs par leur nom
import csv
with open("inventory.csv", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    rows = list(reader)

Pour l’en-tête product,stock,price et la ligne notebook,12,2.50, le premier dictionnaire est {'product': 'notebook', 'stock': '12', 'price': '2.50'}. reader.fieldnames donne les noms de l’en-tête. L’en-tête est consommé automatiquement ; appeler next(reader) passerait le premier enregistrement de données.

Utilise row["stock"] pour sélectionner le stock, même si les colonnes changent d’ordre. Convertis-le avec int() pour comparer les quantités. Les valeurs restent des chaînes ; les noms de colonnes ne donnent pas de types numériques à l’objet reader.

Filtrer et calculer un total

Supposons que le tableau contienne un stock de 12 cahiers au prix de 2,50, de 3 stylos à 1,20, de 0 agrafeuse à 7,95 et de 25 chemises à 0,80.

low = [r for r in rows if int(r["stock"]) < 5]
value = sum(int(r["stock"]) * float(r["price"]) for r in rows)

low contient les lignes du stylo et de l’agrafeuse. La valeur est de 53,6 € : les cahiers y contribuent pour 30, les stylos pour 3,6, les agrafeuses pour 0 et les chemises pour 20. Le filtre utilise le stock, tandis que le total utilise à la fois le stock et le prix.

Distinguer les clés manquantes des valeurs manquantes

Les noms de l’en-tête doivent correspondre exactement. Name et name sont des clés différentes. Un espace après une virgule peut faire partie d’un en-tête ; skipinitialspace=True supprime les espaces qui suivent immédiatement les séparateurs.

Un en-tête name,quiz1,quiz2 avec les données Ben,7 produit {'name': 'Ben', 'quiz1': '7', 'quiz2': None}. La clé existe, mais sa valeur manque. int(None) lève TypeError. Un champ présent mais vide vaut "", et sa conversion lève ValueError. Une clé absente de l’en-tête provoque en revanche KeyError lors de l’accès.

Avec les données Cara,1,2,3, les champs en trop sont réunis sous la forme None: ['3'] ; les champs nommés contiennent toujours "Cara", "1" et "2". Vérifie la structure d’une ligne lorsque l’exactitude des totaux dépend de chaque champ.

Écrire certaines colonnes
with open("reorder.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["product", "stock"])
    writer.writeheader()
    for r in low:
        writer.writerow({"product": r["product"], "stock": r["stock"]})

fieldnames fixe l’ordre de sortie, quel que soit l’ordre du dictionnaire. Les clés manquantes du dictionnaire deviennent des champs vides. Par défaut, les clés en trop lèvent ValueError : passer à cet objet writer à deux colonnes un dictionnaire d’inventaire contenant price échoue. Construis le dictionnaire plus petit comme indiqué, ou choisis extrasaction="ignore" lorsque l’omission des champs en trop est volontaire.

Points clés

  • DictReader consomme l’en-tête et renvoie des dictionnaires dont les valeurs sont des chaînes.
  • Les noms de l’en-tête doivent correspondre exactement aux clés utilisées pour l’accès.
  • Un champ manquant vaut par défaut None ; un champ présent mais vide vaut "".
  • Par défaut, les champs en trop sont placés sous la clé None.
  • DictWriter a besoin de fieldnames pour fixer l’ordre des colonnes.
  • Les clés manquantes en sortie deviennent des champs vides ; les clés inattendues lèvent par défaut ValueError.
4

Gérer les erreurs avec try et except

Les noms de fichiers peuvent être incorrects, l’accès peut être refusé et une colonne numérique peut contenir un mot. Une exception marque le point où l’exécution normale ne peut plus continuer. Tu liras des rapports d’erreur, intercepteras les problèmes attendus et sépareras le traitement en cas de réussite du nettoyage. Suivre ensuite les erreurs à travers les appels de fonctions t’aidera à placer leur gestion là où une décision utile peut être prise, notamment pour réessayer une lecture ou signaler une ligne rejetée.

4.1 Comprendre un rapport d’erreur

Une exception est un objet qui signale un problème pendant l’exécution. La lever interrompt l’exécution normale. Si aucun gestionnaire ne la traite, Python termine le programme avec une trace d’appels, un rapport des appels qui ont conduit à l’erreur.

Commencer par le bas
def average(values):
    return sum(values) / len(values)

def report():
    scores = []
    print(average(scores))

report()

La trace d’appels se termine par ZeroDivisionError: division by zero. Commence par là : le type nomme la nature du problème et le message donne des détails. L’entrée située juste au-dessus pointe vers la division dans average(). Les entrées précédentes montrent l’appel depuis report() et l’appel initial à report(). La liste est vide, donc sa longueur est 0. La ligne signalée comme défaillante est celle où le problème apparaît ; l’affectation précédente de la liste vide explique son origine.

Choisir le type correspondant
TypeCause habituelle
ValueErrorint("3.5") : une chaîne contenant une valeur inacceptable
TypeErrorlen(5) : une opération sur un type d’objet incorrect
ZeroDivisionErrorUne division par zéro
IndexErrorLa lecture d’une position inexistante dans une liste
KeyErrorL’accès à une clé absente d’un dictionnaire
NameErrorL’utilisation d’un nom non défini
AttributeErrorLa demande à un objet d’un attribut qu’il ne possède pas

int("abc") reçoit un type d’entrée autorisé, une chaîne, mais ne peut pas interpréter cette valeur comme un entier. "5" + 3 mélange en revanche des types incompatibles pour l’addition. Une chaîne contenant des chiffres reste une chaîne.

Les opérations sur les fichiers ont des types plus précis : FileNotFoundError pour un chemin introuvable, PermissionError pour un accès refusé et FileExistsError pour la création d’un fichier existant avec "x". Ouvrir un répertoire comme un fichier ordinaire peut lever IsADirectoryError. Décoder des octets avec un encodage incompatible peut lever UnicodeDecodeError.

Comprendre l’arbre généalogique

Les classes d’exceptions forment une hiérarchie. Un gestionnaire visant une classe parente peut intercepter ses classes enfants :

  • OSError est la classe parente des erreurs courantes du système de fichiers, notamment FileNotFoundError et PermissionError.
  • LookupError est la classe parente d’IndexError et de KeyError.
  • ArithmeticError est la classe parente de ZeroDivisionError.
  • UnicodeDecodeError descend de ValueError.

Ces branches descendent de Exception, qui descend de BaseException. KeyboardInterrupt et SystemExit descendent quant à elles directement de BaseException. Cette distinction permet à except Exception de laisser passer l’interruption par l’utilisateur et la sortie du programme.

Distinguer les problèmes de syntaxe, d’exécution et de logique

Des deux-points ou une parenthèse fermante manquants peuvent empêcher Python d’analyser un script. La SyntaxError qui en résulte se produit avant l’exécution du script : un try dans ce même script ne peut donc pas l’intercepter. Une exception d’exécution se produit pendant l’exécution d’un code valide. Une erreur de logique produit une réponse incorrecte sans nécessairement lever d’exception, par exemple lorsqu’un total est divisé par le mauvais nombre d’éléments.

Points clés

  • Lis d’abord le type d’exception et le message au bas d’une trace d’appels.
  • Utilise les entrées des appels pour remonter de la valeur problématique jusqu’à son origine.
  • ValueError concerne une valeur inacceptable ; TypeError concerne un type inadapté.
  • Un gestionnaire visant une exception parente intercepte aussi ses classes d’exceptions enfants.
  • Les erreurs de syntaxe, d’exécution et de logique surviennent de différentes façons.

4.2 Intercepter un problème là où il peut être géré

Une instruction try exécute du code susceptible d’échouer et offre une voie de reprise pour certaines exceptions. Le gestionnaire doit correspondre au problème que le programme attend et auquel il sait répondre.

Suivre le déroulement
while True:
    try:
        age = int(input("Age: "))
        break
    except ValueError:
        print("Please enter a whole number, like 34.")
print("Next year you will be", age + 1)

Saisir « twenty » amène int() à lever ValueError. Python ignore le reste du try, y compris break, et exécute le gestionnaire correspondant. La boucle demande ensuite une nouvelle saisie. Saisir « 34 » permet au try de se terminer par break : le programme quitte donc la boucle et affiche « Next year you will be 35 ».

Un gestionnaire ne reprend pas à l’instruction qui a échoué. L’exécution continue après l’instruction try, sauf si le gestionnaire lui-même modifie ce déroulement. Si aucun gestionnaire ne correspond, l’exception poursuit sa propagation.

Traiter différemment les échecs différents
try:
    result = int(a) / int(b)
except ValueError:
    print("Both values must be whole numbers.")
except ZeroDivisionError:
    print("The second value cannot be 0.")

Une conversion invalide et un diviseur nul nécessitent des messages différents. Si la réponse doit être identique, regroupe les types dans un tuple : except (ValueError, ZeroDivisionError):. Les parenthèses fonctionnent dans toutes les versions de Python 3. Python 3.14 permet aussi une liste sans parenthèses lorsqu’il n’y a pas de partie as ; la forme avec tuple reste claire d’une version à l’autre.

Python examine les clauses de haut en bas et exécute la première qui correspond. Place FileNotFoundError avant son type parent OSError si un fichier manquant nécessite une réponse particulière. Inverser leur ordre rend le gestionnaire spécifique inaccessible.

Utiliser le message sans masquer d’autres bugs
try:
    quantity = int(text)
except ValueError as err:
    print("Cannot read quantity:", err)

err est l’objet exception ; l’afficher montre son message. type(err).__name__ donne le nom de sa classe. Python supprime la liaison de err à la fin du gestionnaire : copie donc son message dans une autre variable à l’intérieur du bloc si tu en as besoin plus tard.

Garde le try court. Place les calculs ultérieurs hors du gestionnaire de conversion lorsque leurs échecs nécessiteraient un traitement différent. except Exception: peut masquer des bugs comme une variable non définie. Un except: sans type est encore plus large : il intercepte aussi KeyboardInterrupt et SystemExit.

Tester l’opération plutôt qu’une approximation

Tester text.isdigit() ne vérifie pas tout ce que int() accepte. "-5" et " 34" échouent à ce test, mais sont convertis avec succès ; "²" réussit le test, mais ne se convertit pas avec int(). Essayer la conversion et intercepter ValueError applique les règles propres à la conversion.

Lorsque tu gères des données invalides, effectue une action visible ou consigne le problème. Un except ValueError: pass vide peut laisser le programme continuer avec des résultats manquants et sans aucune trace du problème.

Points clés

  • Une exception fait ignorer le reste du code try et exécuter le premier gestionnaire correspondant.
  • Utilise des types précis et place les gestionnaires de classes enfants avant ceux des classes parentes.
  • Regroupe les types dans un tuple lorsque la réponse à l’erreur est la même.
  • except ... as err donne accès au message à l’intérieur du gestionnaire.
  • Limite le try aux opérations concernées afin que les messages décrivent l’opération qui a réellement échoué.
  • Essaie directement la conversion numérique lorsque tu dois vérifier ce qu’elle accepte.

4.3 Réussite, nettoyage et erreurs entre fonctions

Une instruction try peut séparer l’opération susceptible d’échouer, la gestion de l’erreur, le traitement en cas de réussite et le nettoyage. Une exception peut aussi quitter une fonction et être gérée par son appelant.

Donner son propre bloc au traitement en cas de réussite
try:
    x = 10 / int(text)
except ValueError:
    print("not a number")
except ZeroDivisionError:
    print("zero")
else:
    print("result", x)
finally:
    print("done")

Avec text = "4", le programme affiche « result 2.5 » et « done ». Avec "abc", il affiche « not a number » et « done » ; avec "0", il affiche « zero » et « done ».

else s’exécute lorsque le try se termine normalement sans exception. Il ne s’exécute pas après qu’un gestionnaire a traité une erreur. Il est aussi ignoré lorsque return, break ou continue fait quitter le try prématurément. Les erreurs levées dans else ne sont pas interceptées par les clauses except précédentes de cette instruction : le traitement en cas de réussite ne partage donc pas accidentellement les gestionnaires de l’opération susceptible d’échouer.

Exécuter le nettoyage quelle que soit la sortie

finally s’exécute lorsque le flot d’exécution quitte l’instruction : après une réussite, après une exception gérée et avant qu’une exception non gérée poursuive sa propagation. Il s’exécute aussi avant qu’un retour en attente soit effectué.

def label():
    try:
        return "from try"
    finally:
        print("finally ran")

value = label()
print(value)

Ce code affiche « finally ran » puis « from try ». Le retour attendait pendant l’exécution du nettoyage. Pour les fichiers, with assure déjà la fermeture et évite donc généralement de la programmer manuellement dans finally.

Ne place pas de sortie telle que return, break ou continue dans finally. Quitter ainsi le bloc de nettoyage peut abandonner une exception en attente ou remplacer une valeur de retour. Python 3.14 et les versions ultérieures émettent un SyntaxWarning pour ce schéma. Réserve le bloc au nettoyage.

Suivre une exception jusqu’à l’appelant
def read_scores(path):
    with open(path, encoding="utf-8") as f:
        return [int(line) for line in f]

try:
    scores = read_scores("scores.txt")
except FileNotFoundError:
    print("The score file is missing.")

Si l’ouverture échoue, read_scores() n’a pas de gestionnaire : FileNotFoundError se propage donc jusqu’à l’appel dans le try externe. L’appelant la gère et affiche le message. Si une ligne n’est pas un entier, une ValueError suit le même chemin, mais le gestionnaire de fichier manquant ne lui correspond pas.

Choisir le niveau capable d’apporter une réponse utile

Une fonction de lecture peut savoir comment obtenir des données sans savoir si un fichier manquant doit entraîner une nouvelle tentative, l’abandon d’une tâche ou un arrêt propre. Laisser l’exception atteindre l’appelant qui communique avec l’utilisateur lui laisse ce choix. L’intercepter trop tôt et renvoyer une liste vide peut masquer la différence entre un fichier vide et une lecture échouée.

Points clés

  • else ne s’exécute qu’après la fin normale du corps du try.
  • finally s’exécute avant la sortie, notamment lors d’un retour ou d’une exception non gérée.
  • Une exception dans else se trouve hors de portée des gestionnaires précédents de cette instruction.
  • Évite les sorties de finally qui peuvent abandonner des erreurs ou des retours en attente.
  • Les exceptions non gérées se propagent à travers les appels jusqu’à un gestionnaire externe correspondant.

4.4 Gérer les erreurs de fichiers et de lignes

Un programme connaît un échec maîtrisé lorsqu’il réagit à un problème de manière contrôlée et utile. Il peut demander une nouvelle saisie, signaler une ligne ignorée ou s’arrêter avec un message clair. Choisis cette réponse selon l’usage qui sera fait du résultat.

Réessayer après un fichier manquant
while True:
    name = input("File name: ").strip()
    try:
        with open(name, encoding="utf-8") as f:
            text = f.read()
    except FileNotFoundError:
        print(f"No file named '{name}'. Please try again.")
    else:
        break
print(len(text.splitlines()), "lines")

Une ouverture échouée fait ignorer l’affectation et conduit au gestionnaire. La boucle demande une nouvelle saisie. Une lecture réussie conduit à else, interrompt la boucle et laisse text disponible pour le décompte final. Si le bloc a été ouvert, with ferme le fichier quelle que soit la manière dont il est quitté.

Pour différents problèmes de fichier, utilise FileNotFoundError, puis PermissionError, puis un gestionnaire général OSError si d’autres erreurs du système de fichiers nécessitent une réponse. Les clauses spécifiques doivent venir en premier. Le décodage d’octets invalides est un autre problème ; un message sur un chemin manquant ne le décrirait pas.

Traiter chaque ligne de données séparément

Pour un bilan rapide des ventes, supposons que les lignes CSV après l’en-tête soient coffee,4, tea,two, muffin,3, cookie, et juice,5.

import csv
total = 0
skipped = 0
with open("sales.csv", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    next(reader, None)
    for row in reader:
        try:
            if len(row) != 2:
                raise ValueError("expected two fields")
            quantity = int(row[1])
        except ValueError as err:
            skipped += 1
            print(f"sales.csv, ending line {reader.line_num}: {err}")
        else:
            total += quantity
print("Total:", total, "Skipped:", skipped)

Le total des quantités valides est de 12. Le mot « two » et la quantité vide sont rejetés : le nombre de lignes ignorées est donc de 2. La vérification de la ligne transforme aussi un nombre inattendu de champs en erreur de données signalée avant l’accès par indice. Placer try dans la boucle permet de traiter l’enregistrement suivant après un échec ; placer la boucle dans un seul try ferait quitter la boucle au premier échec.

Indiquer précisément les emplacements

Pour les cinq enregistrements d’une seule ligne, les valeurs invalides se terminent aux lignes 3 et 5 du fichier. enumerate(reader, start=2) correspondrait ici à ces numéros de ligne, mais un saut de ligne entre guillemets fait s’étendre un enregistrement CSV sur plusieurs lignes. reader.line_num indique le nombre de lignes physiques consommées par l’objet reader. Préciser qu’il s’agit de la ligne de fin rend les messages exacts pour les enregistrements multilignes.

Décider si un résultat partiel est acceptable

Un comptage exploratoire rapide peut tolérer des lignes ignorées et signalées. Un total financier ou de notes peut nécessiter chaque enregistrement : arrête-toi et demande des données corrigées au lieu de présenter un total partiel comme complet. Indique le fichier, l’emplacement et le problème pour qu’il puisse être corrigé.

Après import sys, sys.exit("Could not open sales.csv") écrit le message sur la sortie d’erreur et quitte le programme avec le code de sortie 1. Cet appel lève SystemExit, que except Exception n’intercepte pas. Utilise des gestionnaires précis pour qu’une erreur de programmation sans rapport ne soit pas présentée à tort comme un problème de fichier.

Points clés

  • Choisis de réessayer, de passer ou d’arrêter selon la tâche.
  • Place la gestion des erreurs de ligne dans la boucle pour continuer après une ligne invalide.
  • Signale les enregistrements ignorés et indique clairement que les résultats sont partiels.
  • Les numéros d’enregistrement CSV peuvent différer des numéros de ligne physique.
  • sys.exit(message) termine le programme avec un message d’erreur et le code de sortie 1.
  • Utilise des gestionnaires précis pour que le message corresponde au problème réel.
5

Lever tes propres exceptions

Les fonctions ont besoin d’un moyen clair de signaler les entrées qu’elles ne peuvent pas traiter. Lever une exception empêche une opération échouée de produire un résultat trompeur et laisse l’appelant choisir une réponse. Tu choisiras des types et des messages parlants, laisseras une erreur existante se propager et préserveras sa cause lorsque tu la transformes. Un court modèle de classe personnalisée donne au programme son propre type d’erreur lorsque les appelants doivent distinguer un problème d’un autre.

5.1 Rejeter des entrées avec raise

Une fonction devrait signaler lorsqu’elle ne peut pas produire un résultat valide. raise déclenche une exception à ce stade, afin que le cheminement invalide ne puisse pas continuer comme si l’opération avait réussi.

Vérifier avant de calculer
def withdraw(balance, amount):
    if amount <= 0:
        raise ValueError(f"amount must be positive, got {amount}")
    if amount > balance:
        raise ValueError(f"amount {amount} is more than the balance {balance}")
    return balance - amount

withdraw(100, 30) renvoie 70. withdraw(100, 150) lève une erreur concernant le solde ; withdraw(100, -5) lève une erreur concernant un montant non positif. Aucun de ces appels qui échouent n’atteint la soustraction.

Une exception levée suit les mêmes règles de gestion qu’une erreur native. Si un gestionnaire correspondant dans la fonction l’intercepte, l’exécution peut y continuer. Sinon, l’exception quitte la fonction et atteint l’appelant. Si aucun gestionnaire n’est trouvé, Python affiche une trace d’appels.

Laisser l’appelant choisir la réponse
balance = 100
amount = 150
try:
    balance = withdraw(balance, amount)
except ValueError as err:
    print(f"Cannot withdraw: {err}")

La fonction indique pourquoi elle ne peut pas effectuer le retrait. L’appelant décide d’afficher un message. Comme l’appel de fonction échoue avant de renvoyer une valeur, l’affectation ne remplace pas l’ancien solde par un résultat. Un autre appelant pourrait demander un montant inférieur ou annuler une opération sans modifier la fonction.

Afficher plutôt un avertissement dans la fonction et renvoyer None peut amener l’appelant à utiliser une valeur invalide dans un calcul ultérieur. Lever une exception maintient le lien entre l’échec et sa cause et fournit à l’appelant un chemin distinct pour gérer l’erreur.

Choisir un type parlant
ProblèmeType adapté
Type d’entrée correct, valeur inacceptableValueError
Type d’objet incorrect pour l’opérationTypeError

Un montant numérique négatif est une valeur inacceptable. Une liste fournie lorsqu’un nombre est nécessaire est d’un type inadapté. Le type d’exception fait partie du comportement de la fonction : les appelants l’utilisent pour choisir les gestionnaires. Ne choisis pas un type simplement parce qu’il t’est familier.

Écrire un message utile

Un message devrait indiquer ce qui était attendu et ce qui a été reçu. f"age must be between 0 and 130, got {age}" indique comment corriger le problème. Un message tel que « erreur » ne fournit aucun détail utile. Limite le message à l’opération qui a échoué ; le code destiné à l’utilisateur peut ajouter le contexte plus général.

raise ValueError("amount must be positive") crée une exception avec un message. raise ValueError est également valide et en crée une sans message. Une simple chaîne n’est pas une exception : raise "error" lève TypeError, car les objets levés doivent dériver de BaseException.

Points clés

  • Lève une exception au point où une fonction ne peut plus continuer correctement.
  • Utilise ValueError pour une valeur inacceptable et TypeError pour un type inadapté.
  • Inclus l’entrée attendue et la valeur reçue dans un message utile.
  • Laisse l’appelant décider comment réagir à l’échec de l’opération.

5.2 Transmettre et nommer les exceptions

Parfois, une fonction constate une erreur, mais ne peut pas achever sa gestion. Elle peut devoir laisser la même erreur se propager, la transformer en une erreur plus utile ou donner son propre type d’exception à un problème précis du programme.

Relancer l’erreur courante
def read_text(path):
    try:
        with open(path, encoding="utf-8") as f:
            return f.read()
    except FileNotFoundError:
        print(f"Missing: {path}")
        raise

Le raise seul dans le gestionnaire relance l’exception courante. Afficher seulement un message terminerait le gestionnaire et la fonction renverrait alors None ; relancer l’exception rend l’échec de la lecture visible pour l’appelant. Un raise seul a besoin d’une exception active à relancer.

Transformer l’erreur en préservant sa cause
def read_price(row):
    try:
        text = row["price"]
    except KeyError as err:
        raise ValueError("row has no 'price' column") from err
    return float(text)

Une clé manquante devient une ValueError dont le message concerne la ligne. from err enregistre la KeyError d’origine comme cause directe. La trace d’appels montre l’erreur d’origine, le lien entre les deux et la nouvelle erreur. L’appelant peut gérer le type transformé tout en conservant la cause de bas niveau pour le débogage.

Ce gestionnaire se limite à l’accès par clé. Une valeur présente telle que "free" échoue plus tard à float(text) avec sa propre ValueError ; elle n’est pas signalée à tort comme une colonne manquante.

Définir un type distinct
class InsufficientFundsError(ValueError):
    pass

Ce schéma crée une classe d’exception personnalisée. Par convention, son nom se termine par Error. Le nom entre parenthèses est son type parent : cette classe est donc une sorte de ValueError.

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(
            f"balance {balance}, requested {amount}"
        )
    return balance - amount

try:
    withdraw(100, 150)
except InsufficientFundsError as err:
    print("Not enough money:", err)

Le programme affiche « Not enough money: balance 100, requested 150 ». Un appelant peut distinguer des fonds insuffisants d’une autre valeur invalide. Si un gestionnaire ValueError apparaissait avant ce gestionnaire spécifique, le type parent intercepterait l’exception en premier.

Choisir le type parent selon la gestion voulue

Dériver de ValueError permet à la fois à un gestionnaire spécifique et à un gestionnaire plus général des erreurs de valeur d’intercepter le type personnalisé. Dériver directement de Exception crée une branche distincte d’erreurs ordinaires : except ValueError ne l’intercepterait donc pas. Un type personnalisé est utile lorsque les appelants ont besoin d’une réponse distincte ; un type natif clair et un message suffisent dans le cas contraire.

Points clés

  • Un raise seul dans un gestionnaire laisse l’exception courante se propager.
  • raise NewError(...) from err enregistre l’erreur d’origine comme cause directe.
  • Une exception personnalisée donne aux appelants un type de problème distinct.
  • La classe parente détermine quels gestionnaires plus généraux peuvent intercepter l’erreur personnalisée.
  • Place un gestionnaire personnalisé spécifique avant le gestionnaire de son type parent.

Fichiers et exceptions en Python : exemples

5 Leçons Interactives

1

Transformer un fichier texte en rapport filtré

13 étapes
Lire des lignes, choisir les modes d’ouverture et enregistrer les enregistrements sélectionnés en délimitant clairement la période d’ouverture des fichiers.
  1. 1
    IntroductionLire, décider, enregistrer

    Un journal d’assistance contient un événement par ligne. Tu veux créer un fichier contenant uniquement les événements qui nécessitent une intervention. Cette tâche combine la lecture, des vérifications sur les chaînes et l’écriture.

    Suis d’abord la manière dont un fichier fournit du texte. Construis ensuite le filtre par petites étapes, en séparant l’entrée de la sortie et en laissant with fermer les deux fichiers à la fin du traitement.

  2. 2
    ExplicationUn fichier fournit des chaînes

    Supposons que events.txt contienne "INFO Ready\nERROR Queue full\n". Son ouverture crée un objet fichier, et non une copie de son texte.

    f.readline() renvoie "INFO Ready\n". Un deuxième appel renvoie "ERROR Queue full\n". Un troisième renvoie "", car le fichier est épuisé. Le saut de ligne reste attaché à la ligne renvoyée ; un texte numérique resterait lui aussi du texte jusqu’à sa conversion explicite.

  3. 3
    DéfiChoisir une méthode de lecture

    Un journal peut être bien plus volumineux que la mémoire disponible. Tu dois examiner chaque ligne une seule fois. Comment le lire et pourquoi ?

    ---reveal---

    Parcours directement le fichier ouvert avec for line in f:. Cette boucle fournit une ligne à la fois sans nécessiter d’abord une chaîne ou une liste contenant tout le fichier. Appeler read() ou readlines() chargerait le contenu restant en mémoire.

  4. 4
    ExempleGarder la lecture dans le bloc
    with open("events.txt", encoding="utf-8") as f:
        first = f.readline()
    print(first.rstrip("\n"))
    

    La lecture a lieu pendant que le fichier est ouvert. Quitter le bloc indenté le ferme ; l’affichage ultérieur utilise la chaîne enregistrée. C’est pourquoi une opération sur first peut avoir lieu ensuite, contrairement à un nouvel appel à f.readline().

  5. 5
    DéfiPrévoir le nettoyage après une erreur

    Dans ce bloc de fichier, supposons que int("oops") lève ValueError. Le code englobant n’a pas de gestionnaire. Le fichier reste-t-il ouvert et with masque-t-il l’erreur ?

    ---reveal---

    Le fichier se ferme lorsque l’exécution quitte le bloc dans lequel elle était entrée. L’erreur se propage tout de même et produit une trace d’appels si rien ne l’intercepte. Le nettoyage automatique limite la durée d’ouverture du fichier ; un gestionnaire except serait nécessaire pour gérer l’erreur.

  6. 6
    ExplicationChoisir le comportement du fichier de sortie

    Le rapport filtré doit remplacer un ancien rapport : ouvre donc un chemin de sortie différent avec "w". Ce mode vide immédiatement un fichier existant.

    Pour un historique d’activité qui conserve les exécutions précédentes, utilise "a". Si un rapport existant doit être protégé contre le remplacement, utilise "x" et gère FileExistsError. La création du fichier exige toujours que les dossiers qui le contiennent existent.

  7. 7
    ExempleÉcrire exactement une ligne

    Pour écrire une ligne sélectionnée, conserve sa fin de ligne d’origine :

    dst.write(line)
    

    Si tu l’as plutôt nettoyée avec strip(), rétablis sa fin de ligne :

    dst.write(cleaned + "\n")
    

    write() n’ajoute aucun séparateur. print(cleaned, file=dst) est une autre façon d’ajouter un saut de ligne, tandis que writelines() attend toujours que les chaînes fournies contiennent les fins de ligne nécessaires.

  8. 8
    DéfiPrévoir le résultat de deux exécutions

    En partant sans fichier, un programme s’exécute deux fois. À chaque exécution, il ouvre "runs.txt" en mode ajout et appelle f.write("OK"). Quel texte est enregistré ?

    ---reveal---

    Le fichier contient "OKOK". Le mode ajout conserve le résultat de la première exécution, mais ni le mode ni write() n’ajoutent de saut de ligne. Écrire "OK\n" produirait plutôt une ligne par exécution. Une ouverture en mode "w" ne laisserait que le dernier "OK".

  9. 9
    ExempleNettoyer avant de sélectionner

    Notre journal utilise le premier mot comme niveau. Commence chaque passage par :

    cleaned = line.strip()
    if not cleaned:
        continue
    level = cleaned.split(maxsplit=1)[0]
    

    La vérification des lignes vides évite d’accéder par indice à une liste vide. Conserver séparément la line d’origine permet de préserver son espacement en sortie. Seule la copie nettoyée sert à identifier le niveau.

  10. 10
    DéfiVérifier la bonne partie

    Le journal contient « INFO ERROR counter reset » et « ERROR Queue full ». Quel test sur le niveau n’enregistre que le second enregistrement ?

    ---reveal---

    Teste level == "ERROR" après avoir extrait le premier mot. Rechercher "ERROR" n’importe où enregistrerait aussi l’enregistrement d’information, car le mot apparaît dans son message. Le format indique où trouver la catégorie à sélectionner.

  11. 11
    ExempleAssembler le filtre
    count = 0
    with open("events.txt", encoding="utf-8") as src, open("urgent.txt", "w", encoding="utf-8") as dst:
        for line in src:
            cleaned = line.strip()
            if not cleaned:
                continue
            if cleaned.split(maxsplit=1)[0] == "ERROR":
                dst.write(line)
                count += 1
    print(count, "saved")
    

    Le compteur ne change que lorsqu’un enregistrement est écrit. Les deux fichiers se ferment avant l’affichage du compte.

  12. 12
    DéfiComprendre la perte d’une source

    Une personne remplace le nom de sortie par "events.txt" tout en gardant "w". Pourquoi le filtre risque-t-il maintenant de ne rien enregistrer, alors que la source a été ouverte en premier ?

    ---reveal---

    La seconde ouverture vide le même fichier sous-jacent avant que la boucle le lise. Le premier objet fichier n’a pas enregistré de copie distincte de l’ancien texte. Rétablis un chemin de sortie différent afin que la transformation ne puisse pas effacer son entrée à l’ouverture.

  13. 13
    RécapitulatifSuivre une tâche sur fichier avant de l’exécuter

    Pour une transformation de fichier, suis quatre décisions : d’où vient l’entrée, quelle quantité de texte est lue à la fois, ce qui sélectionne un enregistrement et l’effet de l’ouverture du fichier de sortie sur les données existantes.

    Vérifie ensuite les limites des blocs. Les opérations sur les fichiers nécessitent des objets fichier ouverts ; les chaînes, listes et totaux enregistrés peuvent être utilisés après leur fermeture.

2

Localiser les données d’un projet depuis n’importe quel dossier de lancement

9 étapes
Suivre des chemins relatifs, construire des chemins relatifs au script et préparer des dossiers avec pathlib.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionTrouver le dossier de départ
  2. 2
    ExempleSuivre un lancement
  3. 3
    DéfiChanger de dossier de lancement
  4. 4
    ConseilExaminer avant de changer le chemin
  5. 5
    ExempleConstruire le chemin à partir du script
  6. 6
    ExplicationPréparer une destination
  7. 7
    DéfiExaminer un nom et trouver des correspondances
  8. 8
    DéfiVérifier une correction proposée
  9. 9
    RécapitulatifDistinguer l’emplacement de la disponibilité
3

Lire un tableau et écrire un rapport à colonnes nommées

13 étapes
Analyser du CSV contenant des champs entre guillemets, convertir des champs numériques et exporter certaines colonnes dans un ordre contrôlé.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionPréserver la structure du tableau
  2. 2
    ExempleLire un enregistrement contenant un champ entre guillemets
  3. 3
    ExempleOuvrir et convertir
  4. 4
    DéfiReconnaître une ligne trop courte
  5. 5
    ExempleÉcrire les valeurs comme des champs
  6. 6
    DéfiGarder un champ d’un seul tenant
  7. 7
    ExplicationUtiliser l’en-tête comme clés
  8. 8
    ExempleFiltrer selon le stock
  9. 9
    DéfiDistinguer un champ manquant d’un champ vide
  10. 10
    ExempleExporter certaines colonnes
  11. 11
    DéfiAjouter un lot ultérieur
  12. 12
    ConseilAdapter les séparateurs et les encodages
  13. 13
    RécapitulatifVérifier la structure et le sens
4

Suivre une erreur depuis une ligne invalide jusqu’à une réponse utile

15 étapes
Lire une trace d’appels, choisir des gestionnaires et distinguer une nouvelle tentative d’ouverture de fichier de la gestion d’une erreur dans une boucle sur les lignes.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionChoisir ce qui peut être repris
  2. 2
    ExempleCommencer par le type d’exception
  3. 3
    DéfiReconnaître un échec différent
  4. 4
    ExempleIntercepter uniquement l’erreur de conversion attendue
  5. 5
    DéfiOrdonner les gestionnaires liés
  6. 6
    ExplicationSéparer le traitement en cas de réussite du nettoyage
  7. 7
    DéfiSuivre une erreur sans correspondance
  8. 8
    LienLaisser l’appelant décider
  9. 9
    ExempleGarder la gestion des erreurs dans la boucle sur les enregistrements
  10. 10
    ExempleSuivre trois enregistrements
  11. 11
    DéfiChanger les limites de la boucle
  12. 12
    ConseilNommer correctement l’emplacement
  13. 13
    DéfiChoisir un résultat complet
  14. 14
    ExempleS’arrêter avec un code de sortie d’erreur
  15. 15
    RécapitulatifPlacer chaque réponse au bon niveau
5

Concevoir le comportement d’une fonction en cas d’erreur

10 étapes
Valider une demande, lever des erreurs utiles et préserver les distinctions et les causes pour les appelants.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionPrévoir un chemin clair en cas d’échec
  2. 2
    ExempleRejeter les demandes invalides
  3. 3
    DéfiSuivre une affectation qui échoue
  4. 4
    ExplicationAdapter le type au problème
  5. 5
    ExempleNommer une insuffisance de places distincte
  6. 6
    DéfiGarder la réponse spécifique accessible
  7. 7
    ExempleRéagir et laisser l’erreur se propager
  8. 8
    ExempleTransformer un échec de bas niveau
  9. 9
    DéfiChoisir la bonne relation
  10. 10
    RécapitulatifGarder une erreur parlante pour l’appelant

Fichiers et exceptions en Python : QCM

50 Questions Pratiques en 5 séries

Série 1 : Lire des fichiers et suivre de petits programmes10 Questions Pratiques

Question 1 sur 10

Un fichier contient "oak\npine". Immédiatement après son ouverture en lecture, que renvoie f.readline() ?
  1. "oak"
  2. ["oak\n", "pine"]
  3. "oak\n"
  4. "oak\npine"
Afficher la réponseMasquer la réponse
Réponse : C
readline() renvoie la ligne suivante sous forme de chaîne et conserve sa fin de ligne : le résultat est donc "oak\n". La méthode ne supprime pas le saut de ligne comme le ferait strip(). La seconde ligne n’a pas de saut de ligne final, mais cela ne change pas la première.

Question 2 sur 10

Le bloc se termine normalement. Qu’est-ce qui s’affiche ?

with open("memo.txt", encoding="utf-8") as f:
    text = f.read()
print(f.closed)
  1. False
  2. True
  3. None
  4. text
Afficher la réponseMasquer la réponse
Réponse : B
Quitter le bloc with ferme le fichier : f.closed vaut donc True. Le nom désigne toujours l’objet fichier ; la fermeture ne le supprime pas. La chaîne stockée dans text reste utilisable, mais le fichier ne peut plus être lu par cet objet fermé.

Question 3 sur 10

Un programme doit ajouter un message d’exécution à un journal tout en conservant tous les messages précédents. Quel mode de fichier texte doit-il utiliser ?
  1. "a"
  2. "w"
  3. "r"
  4. "x"
Afficher la réponseMasquer la réponse
Réponse : A
Le mode ajout, "a", écrit à la fin et conserve le texte existant. Le mode écriture, "w", viderait le journal dès son ouverture. Le mode ajout peut aussi créer un journal manquant, mais le programme doit toujours inclure dans son message tout saut de ligne nécessaire.

Question 4 sur 10

Un terminal travaille dans /work/lab. Il exécute python tools/count.py, qui ouvre "inputs/list.txt". Quel emplacement absolu ce chemin relatif désigne-t-il ?
  1. /work/lab/tools/inputs/list.txt
  2. /work/inputs/list.txt
  3. /inputs/list.txt
  4. /work/lab/inputs/list.txt
Afficher la réponseMasquer la réponse
Réponse : D
Le chemin relatif part de /work/lab et désigne donc /work/lab/inputs/list.txt. Exécuter un script dans tools ne change pas automatiquement le répertoire de travail pour ce dossier. L’emplacement du script et le répertoire du processus sont deux points de départ distincts.

Question 5 sur 10

Pour p = Path("exports/week/report.csv"), que vaut p.stem ?
  1. ".csv"
  2. "report"
  3. "report.csv"
  4. "exports/week"
Afficher la réponseMasquer la réponse
Réponse : B
Le radical est le nom final privé de son dernier suffixe : on obtient "report". La propriété name conserverait le suffixe et donnerait "report.csv". Le parent désigne le dossier contenant le fichier, tandis que le suffixe désigne l’extension finale.

Question 6 sur 10

Avec csv.reader par défaut, quelle liste est lue à partir de l’enregistrement "River, West",6,8 ?
  1. ['River, West', '6', '8']
  2. ['River, West', 6, 8]
  3. ['\"River', ' West\"', '6', '8']
  4. ['River', 'West', '6', '8']
Afficher la réponseMasquer la réponse
Réponse : A
La virgule entre guillemets fait partie d’un seul champ : l’objet reader renvoie donc trois chaînes, le nom du lieu et deux textes numériques. Avec ses paramètres par défaut, il ne convertit pas les chiffres en nombres. Découper à chaque virgule couperait incorrectement le nom du lieu.

Question 7 sur 10

Quelle ligne writer.writerow("Leo") produit-il avec la virgule comme délimiteur par défaut ?
  1. Leo
  2. "Leo"
  3. L,e,o
  4. L e o
Afficher la réponseMasquer la réponse
Réponse : C
Une chaîne est une séquence de caractères : writerow("Leo") traite donc chaque caractère comme un champ et écrit L,e,o. Pour obtenir un seul champ contenant le nom, passe ["Leo"]. L’objet writer attend une séquence de valeurs de champs, et non une chaîne passée seule.

Question 8 sur 10

Un champ de quantité CSV contient la chaîne "many". Quelle exception int(row["quantity"]) lève-t-il ?
  1. TypeError
  2. KeyError
  3. IndexError
  4. ValueError
Afficher la réponseMasquer la réponse
Réponse : D
L’accès réussit et fournit une chaîne, mais "many" n’est pas une représentation valide d’un entier : la conversion lève donc ValueError. TypeError décrirait un type d’entrée inadapté tel que None. Le champ indiqué exclut ici une erreur de clé manquante.

Question 9 sur 10

Qu’est-ce qui s’affiche ?

def read_count(text):
    return 12 / int(text)
try:
    result = read_count("0")
    print("read")
except ValueError:
    print("bad text")
except ZeroDivisionError:
    print("zero")
print("end")
  1. « read », puis « end »
  2. « bad text », puis « end »
  3. « zero », puis « end »
  4. « zero », puis « read »
Afficher la réponseMasquer la réponse
Réponse : C
La chaîne « 0 » est convertie avec succès, mais la division dans la fonction auxiliaire lève ZeroDivisionError. L’exception se propage à l’appelant, fait ignorer le reste du corps try et atteint le gestionnaire correspondant, qui affiche « zero ». L’exécution affiche ensuite « end » ; une chaîne numérique valide ne déclenche pas le gestionnaire de conversion.

Question 10 sur 10

Une fonction accepte un nombre entier de pages, mais ne peut pas traiter un nombre inférieur à 1. Pour l’entrée -2, quels exception et message conviennent ?
  1. TypeError("pages must be positive, got -2")
  2. ValueError("pages must be positive, got -2")
  3. IndexError("pages must be positive, got -2")
  4. NameError("pages must be positive, got -2")
Afficher la réponseMasquer la réponse
Réponse : B
L’entrée est déjà un entier : son type est donc acceptable, mais sa valeur ne respecte pas l’exigence. ValueError exprime ce problème et le message indique l’intervalle attendu et la valeur reçue. TypeError décrirait incorrectement le type de l’entrée.
Série 2 : Choisir des méthodes et gérer les échecs attendus10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Un journal contient les lignes "09:10 INFO ERROR count reset" et "09:12 ERROR Network down". Le niveau est le deuxième champ séparé par des caractères d’espacement. Quelle condition sélectionne uniquement les enregistrements de niveau erreur ?
  1. "ERROR" in line
  2. line.startswith("ERROR")
  3. line.split()[2] == "ERROR"
  4. line.split()[1] == "ERROR"
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Un fichier contient "12\n15\n". Quel couple obtient-on avec first = f.read() suivi de second = f.read() sur un même objet fichier venant d’être ouvert en lecture ?
  1. first == "12\n15\n", second == ""
  2. first == "12\n", second == "15\n"
  3. first == "12\n15\n", second == first
  4. first == [12, 15], second == []
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Sous Windows, pourquoi le littéral de chaîne Python "C:\new\tasks.txt" peut-il ne pas désigner le fichier voulu ?
  1. Le nom du lecteur rend ce chemin relatif au lecteur.
  2. Les barres obliques inverses ne fonctionnent que dans les chemins relatifs.
  3. Les barres obliques inverses commencent des séquences de saut de ligne et de tabulation.
  4. Un chemin absolu doit commencer par une barre oblique.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Un fichier commence par city,visitors et Mesa,24. Après reader = csv.DictReader(f), le programme appelle next(reader) une fois, puis lance une boucle. Pourquoi Mesa est-elle absente de cette boucle ?
  1. L’objet reader traite les valeurs numériques comme des noms de champs.
  2. L’appel a consommé le premier enregistrement de données.
  3. L’objet reader ne peut pas utiliser un en-tête en minuscules.
  4. La boucle ignore les enregistrements dont les noms sont sans guillemets.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

La première ligne est label;count, mais l’objet reader CSV par défaut renvoie ["label;count"]. Quel paramètre de lecture correspond à ce fichier ?
  1. skipinitialspace=True
  2. delimiter=","
  3. quoting=csv.QUOTE_ALL
  4. delimiter=";"
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Qu’est-ce qui s’affiche ?

try:
    value = 18 / int("0")
except ZeroDivisionError:
    print("zero")
else:
    print("success")
finally:
    print("closed")
  1. « success », puis « closed »
  2. « zero », puis « closed »
  3. « zero », puis « success »
  4. « closed », puis « zero »
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Un total complet des versements d’une subvention est requis. Un fichier CSV contient un montant invalide parmi 200 enregistrements. Pourquoi ignorer ce montant et afficher le reste comme le total complet est-il un mauvais choix de gestion de l’erreur ?
  1. Le total omet un versement requis sans le signaler.
  2. L’échec de conversion empêche de rouvrir le fichier.
  3. Le fait de l’ignorer modifie tous les autres montants.
  4. Un CSV ne peut pas contenir des lignes valides et invalides.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Une FileNotFoundError se produit dans un try. Le premier gestionnaire est except OSError: print("file problem") et le second est except FileNotFoundError: print("missing"). Qu’est-ce qui s’affiche ?
  1. « missing »
  2. « file problem », puis « missing »
  3. « file problem »
  4. Aucun gestionnaire ne correspond.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Dans un bloc except ValueError:, quelle instruction transmet la même exception active à l’appelant ?
  1. return
  2. raise
  3. continue
  4. pass
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Qu’est-ce qui s’affiche ?

def reserve(n):
    if n <= 0:
        raise ValueError("positive count required")
    return n * 2
result = 7
try:
    result = reserve(0)
except ValueError:
    print(result)
  1. 7
  2. 0
  3. None
  4. 14
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Série 3 : Traiter des fichiers et suivre les chemins de gestion des erreurs10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Un fichier contient uniquement « bad ». Qu’est-ce qui s’affiche ?

try:
    with open("one.txt", encoding="utf-8") as f:
        value = int(f.readline())
except ValueError:
    print(f.closed)
  1. False
  2. True
  3. Une trace d’appels NameError.
  4. Une trace d’appels FileNotFoundError.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Un nouveau fichier est écrit avec f.writelines(["red", "blue\n"]), puis rouvert en mode ajout pour écrire "green\n". Quel texte contient-il ?
  1. "redblue\ngreen\n"
  2. "red\nblue\ngreen\n"
  3. "green\n"
  4. "redbluegreen\n"
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Les dossiers results et results/daily sont absents. Que faut-il exécuter avant d’écrire avec Path("results/daily/run.txt").write_text("ok", encoding="utf-8") ?
  1. Path("results/daily").mkdir(exist_ok=True)
  2. Path("results/daily/run.txt").mkdir(parents=True)
  3. Path("results/daily").exists()
  4. Path("results/daily").mkdir(parents=True, exist_ok=True)
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Un programme qui ajoute des données n’écrit un en-tête que lorsque not p.exists(). Le fichier au chemin indiqué existe, mais contient zéro octet. Quelle condition donne aussi à ce fichier l’en-tête nécessaire ?
  1. p.exists() and p.stat().st_size > 0
  2. not p.exists() and p.stat().st_size == 0
  3. not p.exists() or p.stat().st_size == 0
  4. p.exists()
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Un DictReader par défaut a pour en-tête name,first,second et lit Inez,5. Quelle valeur est stockée sous "second" et que se passe-t-il lorsqu’elle est passée à int() ?
  1. None ; lève TypeError.
  2. "" ; lève ValueError.
  3. "5" ; renvoie 5.
  4. Aucune clé ; lève KeyError.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Quelle exception l’accès au dictionnaire {"east": 4}["west"] lève-t-il ?
  1. IndexError
  2. ValueError
  3. KeyError
  4. NameError
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Que reçoit l’appelant et qu’est-ce qui s’affiche en premier ?

def choose():
    try:
        return 11
    finally:
        print("leaving")
x = choose()
  1. Il reçoit None ; « leaving » s’affiche d’abord.
  2. Il reçoit 11 ; rien ne s’affiche.
  3. Il reçoit « leaving » ; 11 s’affiche d’abord.
  4. Il reçoit 11 ; « leaving » s’affiche d’abord.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Un bilan CSV doit signaler les lignes numériques mal formées et continuer avec les enregistrements suivants. Où placer le try/except ValueError de la conversion ?
  1. Autour de toute la boucle, hors de son corps.
  2. Dans la boucle, autour de la conversion de chaque ligne.
  3. Après la boucle, autour de l’affichage final.
  4. Uniquement autour de l’appel initial à open().
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Avec class LimitError(ValueError): pass, une LimitError est levée. Que se passe-t-il si except ValueError: apparaît avant except LimitError: ?
  1. Aucune clause ne correspond au type personnalisé.
  2. Seul le gestionnaire ValueError s’exécute.
  3. Les deux gestionnaires s’exécutent dans l’ordre écrit.
  4. Seul le gestionnaire LimitError s’exécute.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Après avoir supprimé les caractères d’espacement aux extrémités et passé les lignes vides, un analyseur exécute parts = line.split(maxsplit=2). Les enregistrements doivent contenir une date, un niveau et un message, mais certains ne contiennent qu’une date. Quelle vérification doit précéder parts[1] et parts[2] ?
  1. len(parts) == 3
  2. line.endswith("\n")
  3. len(line) > 3
  4. " " in parts[0]
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Série 4 : Diagnostiquer des données incomplètes et des gestionnaires trompeurs10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

À la fin du fichier, que renvoie f.readline() ?
  1. None
  2. "\n"
  3. []
  4. ""
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

data.txt contient trois enregistrements. Un programme l’ouvre avec "r", puis ouvre le même chemin avec "w", et commence seulement ensuite à lire avec le premier objet fichier. Pourquoi cela risque-t-il de faire perdre les données d’entrée ?
  1. Le mode lecture supprime le saut de ligne final avant l’écriture.
  2. Le premier objet fichier passe automatiquement en mode ajout.
  3. L’ouverture en écriture vide le fichier avant le début de la lecture.
  4. L’objet fichier en écriture copie chaque ligne avant de la remplacer.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

p.exists() renvoie True, mais le fichier est supprimé avant open(p, encoding="utf-8"). De quoi un programme robuste a-t-il encore besoin lors de cette ouverture ?
  1. D’un gestionnaire de fichier manquant avec une réponse utile.
  2. D’une seconde vérification d’existence qui garantit l’accès.
  3. Du mode écriture pour recréer vide le fichier d’entrée attendu.
  4. D’un nettoyage qui supprime le nom du fichier manquant.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Un script doit lire data/menu.txt à côté de son propre emplacement, quel que soit le dossier de lancement. Quelle expression construit ce chemin dans le script ?
  1. Path.cwd() / "data" / "menu.txt"
  2. Path(__file__).resolve().parent / "data" / "menu.txt"
  3. Path(__file__) / "data" / "menu.txt"
  4. Path("data") / "menu.txt"
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Un fichier CSV UTF-8 commence par un indicateur d’ordre des octets. Avec encoding="utf-8", sa première clé d’en-tête est "\ufeffcode". Quel changement à l’ouverture supprime le marqueur tout en préservant le texte UTF-8 ?
  1. Utiliser encoding="utf-8-sig" pour le fichier.
  2. Utiliser newline="\n" au lieu de newline="".
  3. Utiliser delimiter=";" au lieu d’une virgule.
  4. Utiliser skipinitialspace=True pour tous les champs.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Une ligne est {"title": "Map", "stock": "4", "cost": "3.50"}. Un DictWriter par défaut utilise fieldnames=["title", "stock"]. Que se passe-t-il lorsqu’il écrit toute la ligne sans modification ?
  1. Il écrit deux champs et omet cost.
  2. Il ajoute automatiquement cost à l’en-tête.
  3. Il lève ValueError pour la clé en trop.
  4. Il écrit cost comme troisième champ sans nom.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Une boucle de saisie intercepte la ValueError de int(text). Ce gestionnaire affiche missing_name, qui n’a jamais été défini. Que devient la nouvelle NameError ?
  1. Le même except ValueError réessaie automatiquement.
  2. Elle se transforme en erreur de conversion d’origine.
  3. Le gestionnaire la supprime et se termine normalement.
  4. Elle se propage sauf si un gestionnaire externe l’intercepte.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Après un en-tête, un enregistrement CSV commence par "North à la ligne physique 2 et se termine par Hall",7 à la ligne 3. Après sa lecture, quel emplacement reader.line_num indique-t-il ?
  1. 1
  2. 3
  3. 2
  4. 7
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Une fonction auxiliaire affiche « bad size » et renvoie None pour une taille négative. Son appelant multiplie immédiatement le résultat par 4. Pourquoi lever ValueError lors de la validation améliorerait-il la gestion de cet échec ?
  1. Cela renvoie une valeur numérique par défaut pour les calculs ultérieurs.
  2. Cela garantit que l’appelant renouvellera la demande.
  3. Cela signale la taille invalide avant l’échec d’un calcul ultérieur.
  4. Cela signale une erreur de conversion de type avant la validation.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Après avoir intercepté une KeyError sous le nom err, un gestionnaire exécute raise ValueError("missing unit column") from err. Que reçoit l’appelant et quelle cause est préservée ?
  1. Une KeyError causée par la ValueError.
  2. Une ValueError causée par la KeyError.
  3. Une ValueError sans cause antérieure.
  4. Un retour normal avec les deux messages.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Série 5 : Combiner le traitement des fichiers avec une gestion fiable des erreurs10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Un programme entre dans with open("source.txt", encoding="utf-8") as src, open("new.txt", "x", encoding="utf-8") as dst:. La source s’ouvre, mais new.txt existe. Que deviennent src et le corps du bloc ?
  1. src se ferme ; FileExistsError empêche l’exécution du corps.
  2. src reste ouvert ; le corps s’exécute sans destination.
  3. src se ferme ; le corps ajoute du texte à la destination.
  4. src reste ouvert ; le corps remplace la destination.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Un journal contient "10:00 INFO ERROR resolved", "10:01 ERROR Disk slow" et "10:02 ERROR Disk full". Le deuxième champ est le niveau. Après filtrage sur le niveau erreur, combien d’enregistrements sont enregistrés ?
  1. 1
  2. 0
  3. 3
  4. 2
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Un processus démarre dans /srv/course, exécute tools/read.py et ouvre "../shared/items.txt". Quel chemin demande-t-il ?
  1. /srv/course/shared/items.txt
  2. /srv/shared/items.txt
  3. /srv/course/tools/shared/items.txt
  4. /shared/items.txt
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Un objet writer CSV par défaut reçoit ["Vale, East", None, 3]. Quel enregistrement est produit, sans tenir compte de sa fin de ligne ?
  1. Vale, East,None,3
  2. "Vale, East",,3
  3. "Vale, East",None,3
  4. Vale,East,,3
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Un script divise 30 par le nombre 5 écrit en dur alors que le nombre d’éléments voulu est 6. Il affiche 6.0 sans exception. De quel type de problème s’agit-il ?
  1. Une erreur de syntaxe causée par le diviseur.
  2. Une TypeError dans la division numérique.
  3. Une erreur de logique dans le nombre choisi.
  4. Une ZeroDivisionError dans le total.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Qu’est-ce qui s’affiche avant que l’erreur se propage ?

try:
    n = int("2")
except ValueError:
    print("bad input")
else:
    print("ready")
    result = 9 / 0
finally:
    print("cleanup")
  1. « bad input », puis « cleanup »
  2. « ready » uniquement
  3. « cleanup » uniquement
  4. « ready », puis « cleanup »
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Un analyseur doit accepter toutes les chaînes acceptées par int(), y compris celles qui commencent par des espaces et comportent un signe. Pourquoi essayer int(text) dans try au lieu d’exiger d’abord text.isdigit() ?
  1. Les opérations acceptent des ensembles de chaînes différents.
  2. isdigit() convertit les chaînes avec signe en entiers.
  3. int() accepte toute chaîne contenant un chiffre.
  4. Une instruction try supprime les espaces de l’entrée.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Un outil exécute sys.exit("Required file unavailable") dans un code couvert par except Exception:. Que se passe-t-il ?
  1. Le gestionnaire reçoit ValueError et réessaie.
  2. L’outil renvoie le message comme une valeur normale.
  3. SystemExit passe le gestionnaire ; le code de sortie est 1.
  4. Le gestionnaire reçoit SystemExit et continue.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Un bilan CSV initialise total = 0 et skipped = 0. Un gestionnaire interne ignore une ligne si elle contient moins de deux champs ou si int(row[1]) échoue. Il ajoute au total les valeurs converties valides. Pour les lignes ["lamp", "8"], ["desk"], ["chair", "bad"] et ["shelf", "5"], quel couple final est indiqué ?
  1. total = 8, skipped = 1
  2. total = 13, skipped = 2
  3. total = 13, skipped = 1
  4. total = 8, skipped = 2
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Avec class ImportDataError(Exception): pass, un appelant n’intercepte que ValueError. Que se passe-t-il lorsque sa fonction auxiliaire lève ImportDataError ?
  1. Elle se propage, car sa classe est hors de la branche ValueError.
  2. Elle est interceptée, car ValueError descend aussi d’Exception.
  3. Elle est interceptée si son message décrit une valeur inacceptable.
  4. Elle devient ValueError lorsque la fonction la transmet à l’appelant.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Tu bloques sur ton propre exercice ? Aide aux Devoirs

Mots-Clés

83 Mots-Clés, chacun avec sa définition

A

Accumulateur
Un accumulateur est une variable mise à jour pendant l’exécution d’une boucle pour construire un résultat, tel qu’un total ou un compte, à partir des enregistrements traités.
La variable errors commence à 0 et augmente de 1 chaque fois que la boucle trouve un enregistrement de niveau erreur.
Appelant
Un appelant est le code qui appelle une fonction et reçoit le résultat qu’elle renvoie ou une exception qu’elle laisse sans gestion.
L’appelant peut intercepter un retrait invalide et demander un montant inférieur sans modifier la fonction auxiliaire de calcul.
AttributeError
Une AttributeError signale une demande d’attribut ou de méthode qu’un objet ne fournit pas.
Appeler "hi".push("!") lève AttributeError, car une chaîne Python ne possède pas de méthode nommée push.

B

Bloc try
Un bloc try contient des opérations dont les exceptions peuvent être gérées par les clauses qui lui sont associées ; en cas d’échec, le code restant est ignoré.
Une conversion de saisie a sa place dans un petit bloc try afin qu’une valeur invalide puisse déclencher une nouvelle demande.

C

Caractère de saut de ligne
Un caractère de saut de ligne, écrit "\n" dans une chaîne Python, marque un saut de ligne ; la dernière ligne d’un fichier peut ne pas avoir de fin de ligne.
Afficher une ligne qui se termine déjà par "\n" ajoute un autre saut de ligne, sauf si la fin ajoutée par print est modifiée.
Chaînage d’exceptions
Le chaînage d’exceptions enregistre une erreur antérieure comme cause directe d’une nouvelle exception au moyen de raise ... from err.
Une clé de prix manquante peut devenir une erreur de ligne plus claire, tandis que la trace d’appels conserve la KeyError d’origine comme cause.
Chaîne brute
Une chaîne brute utilise le préfixe r afin que les barres obliques inverses soient conservées comme caractères littéraux au lieu d’être interprétées comme des séquences d’échappement ordinaires.
Le littéral r"C:\new\table.txt" préserve les séparateurs qui commenceraient sinon des séquences de saut de ligne et de tabulation.
Champ
Un champ est une partie porteuse de sens d’un enregistrement, séparée ou identifiée selon un format connu, comme un niveau de journal ou une quantité CSV.
Dans un journal comportant une date, une heure, un niveau et un message, vérifier le niveau évite de trouver un mot à l’intérieur du message.
Champ en trop
Un champ en trop est une valeur d’enregistrement au-delà du nombre de champs de l’en-tête ; un DictReader par défaut réunit ces valeurs sous la clé None.
Avec deux noms d’en-tête, une ligne à trois valeurs conserve ses valeurs nommées et stocke la valeur en trop dans une liste.
Champ manquant
Un champ manquant est une valeur absente d’un enregistrement CSV trop court ; un DictReader par défaut remplit sa clé d’en-tête connue avec None.
Sous name,score, la ligne Ana a une note manquante ; Ana, contient en revanche une chaîne de note vide.
Chemin
Un chemin décrit l’emplacement d’un fichier ou d’un dossier au moyen de noms et de séparateurs, à partir d’une racine ou d’un autre répertoire connu.
Le chemin data/notes.txt désigne un fichier texte dans le dossier de données situé sous le répertoire de travail courant.
Chemin absolu
Un chemin absolu indique un emplacement à partir de la racine d’un système de fichiers, comme / sur les systèmes de type Unix ou la racine d’un lecteur sous Windows.
L’emplacement /Users/maya/data/notes.txt ne dépend pas du répertoire de travail courant.
Chemin relatif
Un chemin relatif indique un emplacement à partir du répertoire de travail courant du processus : son sens dépend donc de ce dossier de départ.
En partant de project/scripts, ../data/notes.txt pointe vers le dossier de données voisin du projet.
Classe d’exception parente
Une classe d’exception parente est la classe dont dérive une autre classe d’erreur, de sorte que ses gestionnaires correspondent aux instances de ce type enfant.
Faire dériver LimitError de ValueError permet à un gestionnaire ValueError existant de l’intercepter aussi.
Clause else
Une clause else d’une instruction try s’exécute lorsque le corps protégé se termine normalement, sans exception ni sortie anticipée du flot d’exécution.
Une conversion réussie peut conduire à un affichage dans else, tandis qu’une erreur levée lors de cet affichage n’est pas interceptée par les gestionnaires précédents.
Clause finally
Une clause finally effectue le nettoyage lorsque le flot d’exécution quitte une instruction try, notamment avant qu’un retour en attente soit effectué ou qu’une exception non gérée poursuive sa propagation.
Un message de fin dans finally s’affiche même si une conversion échoue et qu’aucun gestionnaire associé ne correspond à son type.
Code de sortie
Un code de sortie est un résultat numérique transmis au système d’exploitation à la fin d’un programme, qui permet à un autre programme de détecter un échec.
sys.exit("Missing input") affiche le message sur la sortie d’erreur et termine le programme avec le code de sortie 1.
Création de répertoire
La création de répertoire crée des dossiers dans le système de fichiers ; mkdir(parents=True) peut aussi créer les dossiers manquants au-dessus de celui demandé.
Crée output/daily avant d’y écrire le rapport, car l’ouverture d’un nouveau fichier de sortie ne crée pas les dossiers.
Création exclusive
La création exclusive ne crée un nouveau fichier que lorsque le chemin est inutilisé et lève FileExistsError si un fichier existe déjà à cet endroit.
Le mode "x" empêche un rapport nouvellement généré de remplacer silencieusement un rapport au même chemin.
CSV
Le CSV est un format texte pour des enregistrements tabulaires composés de champs séparés, avec des règles de mise entre guillemets qui autorisent des séparateurs et des sauts de ligne dans les valeurs.
L’enregistrement "Lopez, Maria",10,8 comporte trois champs, car sa première virgule se trouve dans un nom entre guillemets.

D

Délimiteur
Un délimiteur est le caractère qui sépare les champs dans un format tabulaire, comme une virgule, un point-virgule ou une tabulation choisi pour un objet reader CSV.
Un fichier exporté avec des points-virgules nécessite delimiter=";" pour qu’un objet reader sépare name;score en deux champs.
DictReader
Un DictReader lit les enregistrements de données CSV sous forme de dictionnaires dont les clés proviennent de l’en-tête, tandis que les valeurs des champs restent par défaut des chaînes.
Après l’en-tête name,score, une ligne est accessible avec row["score"] même si l’ordre des colonnes change.
DictWriter
Un DictWriter écrit des dictionnaires sous forme de lignes CSV en utilisant une séquence fournie de noms de champs pour choisir les colonnes et leur ordre.
Un objet writer avec fieldnames=["product", "stock"] exporte ces colonnes lorsqu’il reçoit des dictionnaires correspondants.

E

En-tête
Un en-tête est une ligne de noms de colonnes qui identifie les champs d’un tableau, généralement placée avant les enregistrements de données dans un fichier CSV.
La ligne product,stock,price nomme les colonnes et ne doit pas être passée à une conversion en entier comme une ligne de données.
Encodage
Un encodage est un ensemble de règles qui représentent les caractères sous forme d’octets, utilisé pour écrire du texte et interpréter le texte stocké.
Le texte « café » peut être déformé si un lecteur utilise un encodage différent de celui qui a servi à l’enregistrer.
Enregistrement
Un enregistrement est une ligne complète de champs CSV ; il occupe généralement une ligne physique, mais peut s’étendre sur plusieurs lignes à cause d’un champ entre guillemets.
Une adresse entre guillemets contenant un saut de ligne reste un seul enregistrement lorsqu’elle est lue par le module CSV.
Erreur de logique
Une erreur de logique amène un programme à produire un résultat incorrect à cause d’un raisonnement ou d’opérations erronés, sans nécessairement lever d’exception.
Diviser par un nombre d’éléments incorrect mais non nul peut produire une moyenne plausible alors que le programme s’exécute jusqu’à son terme.
Exception
Une exception est un objet qui signale un échec et interrompt l’exécution normale pendant que Python cherche un gestionnaire correspondant.
Une conversion int("many") échouée lève une exception avant l’exécution de l’instruction suivante dans ce bloc.
Exception personnalisée
Une exception personnalisée est une classe d’erreur définie par le programme qui permet aux appelants de reconnaître un problème particulier séparément des autres échecs.
Une InsufficientFundsError peut déclencher une demande de montant inférieur, tandis que les autres valeurs invalides reçoivent une autre réponse.

É

Échec maîtrisé
Un échec maîtrisé est une réponse contrôlée à un problème, qui fournit des informations utiles et poursuit ou arrête le programme selon la tâche.
Un fichier de rapport manquant entraîne une demande claire de chemin corrigé au lieu d’un plantage déroutant pour l’utilisateur.

F

Fichier fermé
Un fichier fermé est un objet fichier dont l’accès au fichier sous-jacent a pris fin : il n’est donc plus possible de lire ou d’écrire par son intermédiaire.
Après la fin d’un bloc with ayant ouvert un fichier sous le nom f, f.closed vaut True et f.read() lève une ValueError liée à l’accès à un fichier fermé.
Fichier texte
Un fichier texte stocke des caractères sous forme d’octets encodés, généralement organisés en lignes, et conserve ses données après la fin du programme qui l’a écrit.
Un programme lit une liste de notes enregistrée dans un fichier texte au début de l’exécution suivante.
fieldnames
La séquence fieldnames fournit les noms d’en-tête lus par un DictReader ou les clés de sortie attendues et leur ordre pour un DictWriter.
Appeler writeheader() sur un DictWriter écrit les noms dans l’ordre défini par fieldnames.
FileExistsError
Une FileExistsError signale une opération qui exige un chemin inutilisé alors que quelque chose existe déjà à cet emplacement.
Ouvrir un rapport existant avec le mode "x" lève FileExistsError au lieu de remplacer son contenu.
FileNotFoundError
Une FileNotFoundError signale qu’un fichier ou un répertoire demandé est introuvable au chemin utilisé par une opération du système de fichiers.
Un dossier de lancement incorrect peut amener un chemin d’entrée relatif à lever FileNotFoundError même lorsque le fichier existe ailleurs.
Filtre de lignes
Un filtre de lignes sélectionne les enregistrements selon une condition pendant la lecture d’un fichier, ce qui permet au programme de ne conserver que les lignes utiles à une tâche.
Un filtre de journal vérifie le champ du niveau et n’écrit que les enregistrements dont le niveau est égal à "ERROR".
Fin d’enregistrement
Une fin d’enregistrement est la séquence de caractères qu’un objet writer CSV ajoute après une ligne ; l’objet writer par défaut utilise "\r\n".
Ouvrir avec newline="" permet à l’objet writer de fournir ses propres fins de ligne sans seconde conversion.

G

Gestion déléguée
La gestion déléguée laisse une exception à un appelant qui dispose du contexte nécessaire pour choisir une action de reprise utile pour la tâche dans son ensemble.
Une fonction auxiliaire de traitement des données signale l’échec, tandis que la partie en ligne de commande décide s’il faut réessayer, passer un fichier ou s’arrêter.
Gestionnaire d’exception
Un gestionnaire d’exception est un bloc except sélectionné par un type d’exception correspondant pour apporter une réponse contrôlée à une opération échouée.
Un gestionnaire de ValueError peut expliquer qu’une quantité doit être un nombre entier et laisser une boucle englobante demander une nouvelle saisie.
Gestionnaire de contexte
Un gestionnaire de contexte est un objet qui organise le comportement à l’entrée et à la sortie d’un bloc with, notamment la mise à disposition d’un accès et le nettoyage.
Un objet fichier agit comme gestionnaire de contexte afin qu’un programme puisse compter sur sa fermeture automatique à la sortie du bloc.
Gestionnaire spécifique
Un gestionnaire spécifique intercepte une classe d’exception précise, ce qui permet d’attribuer des messages distincts aux problèmes attendus sans masquer tous les bugs.
Place FileNotFoundError avant OSError lorsqu’un fichier manquant nécessite une réponse différente de celle des autres problèmes de fichier.

H

Hiérarchie des exceptions
Une hiérarchie des exceptions est la structure de classes d’erreurs parentes et enfants qui détermine les correspondances avec les gestionnaires de types plus généraux.
Un gestionnaire d’OSError correspond aussi à FileNotFoundError, tandis qu’un gestionnaire de ValueError ne correspond pas à KeyError.

I

IndexError
Une IndexError signale un accès à une position inexistante dans une séquence, par exemple au-delà de la fin d’une liste.
Une ligne CSV trop courte à un seul champ lève IndexError lorsqu’un code utilisant les positions tente d’accéder à son deuxième champ.
Indicateur d’ordre des octets (BOM)
Un indicateur d’ordre des octets est un marqueur d’encodage initial présent dans certains fichiers exportés en UTF-8, qui peut apparaître dans le premier champ s’il est conservé.
La lecture avec encoding="utf-8-sig" supprime le marqueur initial afin que le premier en-tête corresponde au nom voulu.
Instruction raise
Une instruction raise signale explicitement une exception, interrompt le déroulement normal et lance la recherche d’un gestionnaire correspondant.
Une fonction rejette un montant non positif avec raise ValueError("amount must be positive") avant de calculer.
Instruction with
Une instruction with entre dans un bloc géré et organise le nettoyage lorsque le flot d’exécution le quitte ; pour un fichier ouvert, le nettoyage ferme le fichier.
Un fichier ouvert dans un bloc with se ferme même si la conversion d’une ligne dans le bloc lève une erreur.
IsADirectoryError
Une IsADirectoryError signale qu’une opération attend un fichier mais trouve un répertoire à l’emplacement demandé.
Sur les systèmes qui distinguent ce cas, ouvrir un dossier comme un fichier d’entrée ordinaire lève IsADirectoryError.

K

KeyboardInterrupt
Une KeyboardInterrupt signale une interruption par l’utilisateur, généralement avec Ctrl+C, et descend directement de BaseException plutôt que d’Exception.
Un except: sans type peut intercepter Ctrl+C, tandis que except Exception: laisse l’interruption se propager.
KeyError
Une KeyError signale l’accès à une clé absente d’un dictionnaire, notamment lorsque le nom d’un en-tête CSV ne correspond pas à la clé demandée.
L’accès à row["name"] échoue lorsque l’en-tête du tableau a créé la clé "Name" à la place.

L

Liaison de l’exception
Une liaison de l’exception donne un nom à un objet erreur intercepté au moyen de as afin que son type ou son message puisse être examiné dans ce gestionnaire.
Dans except ValueError as err:, afficher err montre le message ; la liaison est supprimée ensuite.

M

Message d’erreur
Un message d’erreur décrit une opération échouée ou une valeur rejetée afin que la personne qui le lit comprenne ce qui s’est passé et ce qu’il faut corriger.
Le message « le nombre de pages doit être positif, valeur reçue : -2 » est plus utile que le seul mot « erreur ».
Mise entre guillemets
La mise entre guillemets entoure un champ de guillemets afin qu’un délimiteur ou un saut de ligne contenu dans sa valeur reste une partie de ce champ.
L’objet reader conserve la virgule à l’intérieur de "River, West", tandis qu’un simple découpage sur les virgules couperait ce nom.
Mode ajout
Le mode ajout ouvre un fichier afin que la nouvelle sortie soit ajoutée à sa fin tout en conservant le contenu existant ; il crée un fichier manquant.
Utiliser "a" pour les messages d’exécution conserve les exécutions précédentes, mais le message doit tout de même contenir son propre saut de ligne.
Mode binaire
Le mode binaire lit et écrit des octets bruts au lieu de chaînes décodées et n’accepte donc pas d’argument d’encodage de texte.
Un mode tel que "rb" désigne une entrée en octets, tandis qu’une entrée texte utilise un mode tel que "r".
Mode d’ouverture
Un mode d’ouverture est un argument de open() qui détermine l’accès autorisé et la manière dont l’ouverture traite le contenu existant au chemin indiqué.
Un journal d’activité utilise "a" pour conserver les messages précédents, tandis qu’un nouveau rapport peut utiliser "w" pour les remplacer.
Motif glob
Un motif glob sélectionne des chemins selon un motif de nom, avec un caractère générique tel que * correspondant à du texte variable dans le répertoire choisi.
Path("logs").glob("*.txt") trouve les chemins des fichiers texte correspondants ; les trier donne un ordre de traitement prévisible.

N

NameError
Une NameError signale l’utilisation d’un nom qui n’a pas de liaison disponible, souvent parce qu’il a été mal orthographié ou n’a jamais reçu d’affectation.
Un gestionnaire qui affiche une variable non définie lève NameError en essayant de signaler le problème d’origine.
Numéro de ligne physique
Un numéro de ligne physique compte les lignes réelles du fichier ; il peut différer du nombre d’enregistrements CSV lorsqu’un champ entre guillemets contient un saut de ligne.
L’attribut line_num de l’objet reader indique la dernière ligne lue pour un enregistrement qui s’étend sur deux lignes.

O

Objet fichier
Un objet fichier est l’objet renvoyé par open() qui fournit au programme des méthodes pour lire ou écrire un fichier ouvert.
Dans with open("notes.txt", encoding="utf-8") as f:, le nom f désigne l’objet fichier.
Objet Path
Un objet Path représente un chemin en Python et fournit des opérations pour assembler ses composants, examiner ses noms et accéder au système de fichiers.
L’expression Path("data") / "scores.txt" construit un emplacement que open() peut accepter directement.
Objet writer CSV
Un objet writer CSV sérialise des séquences de valeurs de champs en enregistrements, en convertissant les valeurs en texte et en appliquant les règles de mise entre guillemets choisies.
Un objet writer met automatiquement entre guillemets un nom de produit contenant une virgule lorsque le programme le fournit comme un seul champ.

P

PermissionError
Une PermissionError signale que le système d’exploitation refuse l’accès demandé par une opération du système de fichiers.
Un fichier d’entrée peut exister mais lever tout de même PermissionError lorsque le programme n’a pas le droit de le lire.
Position dans le fichier
Une position dans le fichier indique où commence la prochaine opération de lecture et avance à mesure que le programme consomme le texte du fichier.
Après que f.read() a consommé le contenu restant, une seconde lecture renvoie une chaîne vide.
Propagation
La propagation fait remonter une exception non gérée à travers les fonctions appelantes jusqu’à ce qu’un gestionnaire correspondant soit trouvé ou que l’exécution se termine.
Une fonction auxiliaire de lecture de fichier peut laisser FileNotFoundError atteindre l’appelant qui sait s’il faut demander un autre chemin.

R

Radical (stem)
Un radical est le dernier composant d’un chemin privé de son dernier suffixe ; il sert notamment à construire des noms de sortie associés à partir d’un nom de fichier.
Pour Path("logs/run.txt"), le radical est "run", tandis que le nom final complet est "run.txt".
Relance d’exception
La relance d’exception transmet l’exception active interceptée avec un raise seul, ce qui permet d’agir localement sans considérer l’échec comme résolu.
Une fonction de lecture affiche le chemin manquant, puis relance l’exception pour que son appelant décide s’il faut demander un autre fichier.
Répertoire de travail courant
Le répertoire de travail courant est le dossier courant du processus, utilisé comme point de départ lorsque Python interprète des chemins relatifs.
Exécuter python tools/report.py depuis la racine du projet ne déplace pas en soi le processus dans le dossier tools.
Répertoire parent
Un répertoire parent est le dossier qui contient un fichier ou un répertoire ; la propriété parent d’un chemin sélectionne cet emplacement englobant.
Pour Path("reports/2026/sales.csv"), le parent est le chemin reports/2026.
Reprise ligne par ligne
La reprise ligne par ligne gère l’échec attendu d’un enregistrement dans la boucle de traitement, ce qui permet d’examiner les enregistrements suivants lorsque c’est autorisé.
Un bilan rapide signale une quantité invalide et incrémente un compteur de lignes ignorées avant de lire l’enregistrement CSV suivant.

S

Suffixe
Un suffixe est la dernière extension d’un nom de fichier, avec son point initial ; il est accessible par la propriété suffix d’un chemin.
Le suffixe de Path("data/sales.csv") est ".csv", ce qu’un programme peut utiliser pour sélectionner des fichiers tabulaires.
Suppression des caractères d’espacement aux extrémités
La suppression des caractères d’espacement aux extrémités retire du texte les caractères d’espacement situés au début ou à la fin, notamment les espaces, les tabulations et les fins de ligne.
Après line.strip(), une ligne contenant uniquement des espaces et un saut de ligne devient une chaîne vide.
SystemExit
Une SystemExit signale une sortie voulue du processus et est levée par sys.exit() hors de la branche ordinaire Exception.
Appeler sys.exit("Missing data") lève SystemExit avec un message et un code de sortie d’échec qu’un gestionnaire ordinaire d’Exception n’intercepte pas.

T

Tampon
Un tampon est une zone temporaire de mémoire qui contient des données pendant une entrée ou une sortie, comme du texte écrit en attente de transfert vers un fichier.
Fermer un fichier de sortie vide son tampon de texte afin que les écritures en attente soient transmises au fichier.
Trace d’appels (traceback)
Une trace d’appels présente la chaîne d’appels qui mène à une exception non gérée et se termine par le type d’exception et un message explicatif.
L’entrée d’appel la plus basse peut désigner la division par la longueur d’une liste vide comme l’opération qui a échoué.
Troncature
La troncature vide le contenu d’un fichier existant lorsqu’il est ouvert en mode écriture, avant que le programme ne fournisse du nouveau texte.
Ouvrir un fichier d’entrée avec "w" détruit les anciens enregistrements, même si le programme n’atteint jamais un appel d’écriture.
TypeError
Une TypeError signale une opération appliquée à un type d’objet inadapté ou à une combinaison incompatible de types d’objets.
Ajouter "5" à 3 lève TypeError, car l’addition de chaînes n’accepte pas un entier comme second opérande.

U

UnicodeDecodeError
Une UnicodeDecodeError signale que les octets stockés ne peuvent pas être décodés selon les règles choisies pour interpréter le texte.
Un lecteur de texte peut lever UnicodeDecodeError lorsque l’encodage réel du fichier ne correspond pas à encoding="utf-8".
UTF-8
UTF-8 est un encodage de texte qui peut représenter tous les caractères Unicode et utilise un nombre variable d’octets par caractère.
Utilise encoding="utf-8" à l’ouverture d’un fichier texte enregistré en UTF-8 pour que ses lettres accentuées soient correctement décodées.

V

Validation
La validation vérifie qu’une entrée satisfait aux exigences d’une opération avant que le programme l’utilise pour produire un résultat.
Une fonction de retrait vérifie que le montant est positif et ne dépasse pas le solde avant de le soustraire.
ValueError
Une ValueError signale qu’une opération a reçu un type d’objet autorisé, mais une valeur qu’elle ne peut pas interpréter ou accepter pour cette tâche.
La chaîne "3.5" est d’un type d’entrée autorisé pour int(), mais elle ne représente pas un entier et lève ValueError.

W

writerow
La méthode writerow écrit une séquence de valeurs de champs sous forme d’un enregistrement CSV, avec les séparateurs, les guillemets et la fin d’enregistrement nécessaires.
Utilise writer.writerow(["Ana", 8.5]) pour un enregistrement à deux champs, et non une seule chaîne déjà assemblée.
writerows
La méthode writerows écrit une séquence de lignes, en traitant chaque ligne fournie comme une séquence de champs formant un enregistrement CSV.
Une liste de listes contenant chacune un nom et une note peut être passée à writerows() pour enregistrer plusieurs enregistrements en un seul appel.

Z

ZeroDivisionError
Une ZeroDivisionError signale une division ou une opération arithmétique apparentée avec un diviseur nul, qui empêche l’obtention d’un résultat numérique.
Un calcul de moyenne lève ZeroDivisionError si la liste est vide et que sa longueur est utilisée comme diviseur.

À propos de cette unité

Par StudeliSignaler une erreur

Crée ton propre Matériel d'Étude

Transforme tes notes, diapos et documents en Guides d'Étude, Questions Pratiques, Flashcards et 6 autres outils.

Commencer