Depuis le temps que les développeurs écrivent du code Python, il a dû y avoir des millions de bugs écrits, détectés et résolus. Je suis sûr que vous en avez vous-même rencontré…
Au fil du temps, les développeurs se sont aperçus qu’il existe certains modèles qui réduisent la probabilité de rencontrer des bugs, vous laissant libre de travailler sur des choses plus intéressantes ! 🎉
Certains de ces modèles correspondent aux patrons de conception et aux principes de conception SOLID dont nous traiterons plus tard dans le cours, mais la PEP 8 possède également ses propres recommandations de programmation, qui vous aideront à écrire du code antibug.
Dans ce chapitre, nous nous pencherons sur certains des cas les plus importants. Allons-y !
Générez des retours cohérents
Voici une fonction de division mal conçue ! Est-ce que vous voyez les quatre types de valeurs différents qu’elle peut retourner ?
def confusing_division(top, bottom):
if bottom == 0:
return False
if top != 0:
if top % bottom == 0:
return top / bottom
return "La division n’est pas entière !"
En fonction des données entrantes, elle peut retourner :
un booléen ;
un nombre (float, ou nombre à virgule flottante) ;
une chaîne de caractères ;
None
, sitop
est égal à 0, et qu’aucune instructionreturn
n’est rencontrée.
Par conséquent, il est très malaisé d’écrire du code capable de gérer ceci. La PEP 8 recommande ce qui suit :
Soit toutes les instructions
return
retournent une valeur, soit aucune ne le fait.Tous les types de retours doivent être les mêmes (sauf s’il y a une très bonne raison de faire autrement !).
Utilisez
return None
plutôt qu’unreturn
nu.
Notre fonction de division pourrait donc être mieux écrite :
def less_confusing_division(top, bottom):
"""Divise "top" par "bottom"."""
if bottom == 0 or top == 0:
return None
if top % bottom != 0:
return None
return top / bottom
Maintenant, notre code qui gère ceci sait qu’il recevra soit un nombre, soit « None », et nous pouvons écrire :
if less_confusing_division(7, 3) is not None:
# fait quelque chose
else:
# fait autre chose
S’il est important de retourner un message d’erreur spécifique (par exemple : « Ne divise pas correctement ! »), alors il vaut mieux lancer et attraper une exception.
Écrivez des chaînes cohérentes
Voici un exemple de syntaxe Python propre, qui peut en fait vous causer des problèmes ! Que fait le code ci-dessous ?
phone_number = "0123456789"
if phone_number[:3] == "012":
print("Yes!")
Premièrement, nous avons pris un tranche du numéro de téléphone, formé de ses 3 premiers caractères une tranche des 3 premiers caractères du numéro de téléphone, et nous avons vérifié si elle était égale à « 012 ». En d’autres termes, nous avons vérifié s’il commence par « 012 ».
Mais que se passerait-il si nous voulions modifier ceci pour vérifier si le numéro de téléphone commence par « 01234 » ? Nous devrons nous souvenir de changer la longueur de la tranche de liste de 3 à 5 :
phone_number = "0123456789"
if phone_number[:5] == "01234":
print("Yes!")
C’est un détail facile à comprendre, mais également facile à oublier lorsque vous modifiez votre code ! Surtout si la chaîne de comparaison réelle se trouve ailleurs :
phone_number = "0123456789"
if phone_number[:5] == MY_START_PHONE_NUMBER:
print("Yes!")
Sauf si nous découvrons quel est le code d’appel (c’est « 01234 »), nous ne pouvons pas savoir si c'est juste. 😐
Mais alors, que pouvons-nous faire d’autre ?
Python est très bon pour donner des solutions faciles à des problèmes courants, et ici il nous donne la fonction str.startswith
, qui fait exactement ce que vous pouvez espérer :
if phone_number.startswith(MY_START_PHONE_NUMBER):
print("Of course!")
C’est une façon beaucoup plus maintenable d’écrire ce code, et elle est même explicitement recommandée par la PEP 8. Connaître les méthodes des types de base comme les strings permet d’écrire du code bien plus lisible et « pythonique » (c’est à dire, qui suit les bonnes pratique du langage Python) :
phone_number = "01234567890"
if phone_number.endswith("7890"):
print("Verily!")
if "345" in phone_number:
print("Affirmative!")
Simplifiez les exceptions
Votre objectif est que votre code ne contienne pas d’erreurs – et une façon facile de les prévenir est d’utiliser les blocs try-except.
Le code ci-dessous demande de façon répétée un index à l’utilisateur, puis écrit les éléments pertinents de la séquence. Mais nous devons vérifier la validité des données entrantes !
Comment allez-vous compléter ce code pour que, si une exception est levée, le programme écrive simplement un message d’erreur pertinent avant de redemander un index ? Prenez quelques minutes pour préparer une réponse, puis regardez la vidéo ci-dessous pour voir une solution…
letters = ["a", "b", "c", "d", "e"]
length = len(letters)
while True:
try:
message = f"Tapez un index de 0 à {length} pour accéder à l'élement : "
index = int(input(message))
print("Vous accédez à l'élément", letters[index])
Alors, qu’avons-nous découvert ici ?
Le bloc try doit couvrir le moins de code possible, pour éviter de masquer d’autres bugs.
N’utilisez jamais la clause
except
nue, car vous risquez de passer sous silence des erreurs critiques, et vous interférerez avec les exceptionsKeyboardInterrupt
etSystemExit
, qui servent à arrêter le programme. 😱
Profitez des recommandations de programmation
La PEP 8 contient beaucoup trop de recommandations de programmation pour que nous puissions toutes les couvrir dans ce cours.
D’une certaine façon, la PEP 8 ressemble à un manuel d’utilisation de machine à laver – c’est très long, avec beaucoup d’instructions dont vous aurez rarement besoin. Mais il est important de connaître les bases (comment ajouter de la lessive, utiliser les réglages courants, et allumer et éteindre la machine), et c’est utile de l’avoir sous la main lorsque vous avez besoin de le consulter !
En résumé
La PEP 8 comprend différentes recommandations de programmation pour vous aider à écrire du code antibug.
Les fonctions doivent retourner un seul type (entier, chaîne, booléen, etc.) et/ou None.
On préfère
str.startswith
etstr.endswith
au tranchage de chaînes, car vous n’avez qu’un élément de votre code à changer lorsque vous les modifiez.Les blocs try doivent être placés de façon à couvrir le moins de code possible.
Les clauses except doivent toujours attraper un type spécifique d’exception.
Maintenant que nous avons terminé notre visite guidée de la PEP 8, allons voir quelques outils automatisés qui peuvent nous aider à écrire du code de qualité, propre, et conforme à la PEP 8 !