Programmation par contrat avec assert

Programmation par contrat avec assert

Cet article est une reprise de l’ancien contenu du site, les anciens propriétaires en sont donc les propriétaires, nous l’avons mis ici en tant qu’hommage.

Le mot-clé assert est un choix populaire en Python en raison de la bibliothèque pytest, que nous avons couverte dans notre section sur les tests unitaires.

En dehors de ce scénario d’utilisation particulier, personne n’est conscient de sa valeur.

Dans les tutoriels, on vous conseille de ne pas l’utiliser pour des vérifications critiques, car il peut disparaître à tout moment !

En fait, si vous lancez Python en utilisant l’option -o (pour « optimize »), les lignes qui contiennent ce mot-clé ne sont pas prises en compte.

Alors, pourquoi prendre la peine d’ajouter cette chose ?

Quel est l’intérêt de quelque chose qui peut disparaître à tout moment ?

Ce n’est pas un problème, c’est en fait un attribut Ma chère.

Nous reconnaissons souvent les premiers effets kisskool de l’assertion suivante :

assert condition

Si la condition n’est pas vraie et que la condition est fausse, nous recevons une erreur AssertionError.

Mais ce que l’on ignore, c’est qu’il existe une autre forme, plus efficace :

assert the condition, « Message on error ».

Elle fait la même chose, mais elle vous permet de fournir un retour d’information à toute personne qui tombe sur l’erreur mentionnée plus haut.

C’est pourquoi elle est si intéressante, car elle vous permet d’ajouter des vérifications complexes dans votre code, ce qui permet aux développeurs d’éviter de faire des erreurs. C’est ce que nous appelons un accord.

Imaginons un programme qui accepte en paramètre un nombre, qui est, par essence, la clé du dictionnaire :

ARTIBUSES = def souquer_les_artibuses(artibuse) : target = ARTIBUSES[artibuse] # un code souquer professionnel suit

Si quelqu’un utilise votre code et insère l’artibuse incorrect (le méchant boucanier !), notre programme échouera en cas de KeyError. Il obligera alors le coupable (le dangereux scélérat !) à examiner le code source pour apprendre le code et découvrir la racine de la confusion. Qu’est-ce que c’est que cette perte de temps pour notre développeur (le fils de snob !).

Une solution est alors proposée :

def souquer_les_artibuses(artibuse) : if artibuse not in ARTIBUSES : raise ValueError( f » »n’est pas un artibuse valide.  » « Use one of the following :  » ) target = ARTIBUSES[artibuseartibuse]

C’est certainement une bonne idée qui est claire et concise.

Cependant, elle présente un problème dans la mesure où, à chaque appel, nous appliquons le poids d’une expérience qui n’est pas pertinente pour le fonctionnement normal de l’application. En réalité, il est probable que la majorité des appels seront effectués en utilisant exactement les bonnes valeurs (logique sinon le programme se planterait) ce qui signifie que notre test n’est pas un poids nécessaire.

Ce problème s’aggrave lorsque les tests deviennent plus nombreux, plus complexes et plus lourds, car la fonction est appelée de plus en plus souvent.

Comment gérer votre désir urgent d’aider l’autre personne, qui est probablement vous un vendredi matin à 3 heures après une course que vous n’auriez pas dû faire au milieu de la semaine, et aussi éviter ce gaspillage de ressources ?

Le ventre de sa course ! Avec la plus grande assurance !

def souquer_les_artibuses(artibuse) : assert artibuse in ARTIBUSES, ( f  » »n’est pas un artibuse valide.  » « Use one of} » ) target = ARTIBUSES[artibuse[artibuse]

En développement, ou lors de la mise en production, nous disposons de toutes les informations et vérifications nécessaires. Le contrat que nous devons exécuter est vérifié. Nous pouvons ajouter au contrat autant de clauses que nous le voulons et autant de clauses que nous le souhaitons !

Une fois que nous sommes prêts à démarrer la production avec des lignes propres, nous démarrons tout en utilisant l’option -o

Les vérifications qui sont effectuées avant une opération sont appelées préconditions dans le langage de la programmation des contrats. Elles sont les plus simples à comprendre et sont les plus utilisées. Cependant, nous avons la possibilité d’effectuer des vérifications à la fin de la fonction. Cela nous permet de confirmer que nous sommes dans une situation cohérente à la fin du programme.

C’est ce que l’on appelle les post-conditions : Elle n’est pas aussi courante et est plus difficile à écrire, mais extrêmement puissante car nous nous concentrons sur une situation de bout en bout (mon résultat est-il supérieur à 3 ? ) et non sur la façon dont nous y arrivons. Il est beaucoup plus facile d’identifier les erreurs que de chercher toutes les combinaisons possibles de ce que vous pourriez faire de mal.

Les effets secondaires du -o

Le saviez-vous ? Python possède également une variable étrange, debug, qui peut être définie à True par défaut. En utilisant -o, cette variable prend la valeur False. Mieux encore, toute condition qui se produit sur la variable __debug__ sera supprimée du code !

if __debug__ : un_dump_log_de_porc()

Pouf, avec -o il n’y a plus de dump.

Il y a même une option -oo pour éliminer les docstrings, et libérer de la mémoire.

Le problème avec assert

Le problème avec assert est que c’est vous. Je parle de vous, le vous du passé qui ne savait pas. En fait, de nombreux développeurs utilisent les assertions dans leur code sans même y penser. Vous décidez d’ajouter votre -o et boum votre code est cassé. C’est une honte de ne pas pouvoir supprimer votre assert sous prétexte qu’une dépendance a été écrite par un adolescent Bachi-bouzouk.

Cependant, assert est très flexible et peut tester pratiquement tout. Il faut un peu d’expérience pour savoir quel est le bon moment pour l’utiliser et quand ne pas le faire.

L’idée générale est la suivante : si l’erreur concerne la fonction principale de votre application, levez toujours une exception. Si, d’autre part, vous vérifiez si les paramètres sont sains et qu’une erreur n’a pas de conséquence négative, vous pourriez (ce n’est pas nécessaire, cependant, une exception ordinaire est la manière correcte de l’utiliser) utiliser assert.

Donc, n’utilisez pas assert pour vérifier la logique de votre application, et aussi pour sauvegarder l’intégrité de vos données contre une erreur.

Une dernière chose : n’utilisez pas assert pour offrir le contrat basé sur les types (comme appeler isinstance ()), puisque mypy et les types hints le font déjà et sont très agréables à utiliser.

sam artois

A propos de l'auteur

Samuel Artois est un développeur Python passionné d'automatisation et de marketing. Depuis plusieurs années, il a développé une expertise solide dans ces domaines et a su mettre ses compétences en pratique sur de nombreux projets.

Laisser un commentaire