Gestion des erreurs

Python propose plusieurs mécanismes pour écrire un code sûr.

Sommaire

Python et le typage dynamique

Python est un langage à typage dynamique, cela signifie qu'une variable peut légalement changer de type au cours d'un programme, cela simplifie souvent le code mais peut engendrer des erreurs sournoises difficiles à détecter.

En NSI, on s'interdira de changer le type d'une variable, à deux exceptions :

def mon_minimum(ma_liste):
    longueur = len(ma_liste)
    if longueur == 0:
        return None
        # une liste vide ne possède pas de minimum
    else:
        mini = ma_liste[0]
        for i in range(1, longueur):
            if mini < ma_liste[i]:
                mini = ma_liste[i]
        return mini
>>> x = mon_minimum([])
>>> type(x)
<class 'NoneType'>
>>> x = mon_minimum([1337, 42, 200])
>>> type(x)
<class 'int'>
>>> x += 0.0     # bof,   conversion implicite
>>> x = float(x) # mieux, conversion explicite
>>> type(x)
<class 'float'>

De nombreux langages interdisent ces pratiques, et vérifient mieux le code ; Python est permissif. Cependant, il existe des outils externes qui peuvent vérifier le code comme si le typage était statique.

Après la première phase d'apprentissage, une bonne pratique est de faire comme si le typage était statique. (Sauf les deux exceptions mentionnées plus haut.)

Annotation de type des fonctions

En NSI, on indiquera les types des paramètres lorsqu'ils sont élémentaires : int, float, bool, str, list. On ne le fera pas dans les cas complexes.

On suivra le modèle :

def ont_même_parité(n: int, m: int) -> bool:
    return n % 2 == m % 2

Utilisation :

>>> ont_même_parité(42, 1337)
False
>>> ont_même_parité(2021, 1337)
True
>>> ont_même_parité(202, 42)
True

assert pour vérifier une condition

Exemple simple

def est_voyelle(lettre: str) -> bool:
    assert len(lettre) == 1, "La chaîne `lettre` ne devrait contenir qu'un seul caractère"
    return lettre in "AEIOUYaeiouy"
>>> est_voyelle("z")
False
>>> est_voyelle("A")
True
>>> est_voyelle("Azerty")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in est_voyelle
AssertionError: La chaîne `lettre` ne devrait contenir qu'un seul caractère

Utilisation utile

Le modèle à utiliser est :
assert <condition_à_vérifier>, <message à transmettre en cas d'erreur>

assert len(lettre) == 1, ("Mauvaise longueur de la chaîne `lettre`", len(lettre), lettre)

Cela permet à l'utilisateur de disposer d'éléments pour apprécier l'erreur de manière plus précise. C'est au développeur de choisir les informations à transmettre, en fonction de la situation.

Générer de meilleurs messages d'erreurs

Nous allons apprendre, avec la POO, à créer nos propres objets, qui ont leurs propres méthodes. Par exemple la méthode min qui renvoie le minimum d'une liste, d'un ensemble... Et bientôt de notre objet... Mais s'il est non vide !

>>> ensemble_vide = set()
>>> min(ensemble_vide)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence

Une erreur de type ValueError est levée, nous pouvons le faire aussi dans notre propre fonction :

raise ValueError("Notre objet est vide")

Il peut être utile de comprendre, ou de lever l'une de ces exceptions suivant la situation :

Pour en savoir plus : la documentation

doctest pour chaque fonction

En terminale NSI, on documentera chaque fonction avec une docstring, que l'on complètera le plus souvent possible en doctest.