Assessing quality of a Python code
Reading time5 minEn bref
Résumé de l’article
Dans l’article sur les bonnes pratiques de programmation, nous vous avons présenté des éléments à garder en tête lors de l’écriture de code.
Dans cet article, nous vous présentons deux outils qui peuvent vous aider à évaluer la qualité d’un code déjà écrit.
De plus, nous introduisons le “type hinting” (annotations de type), qui peut vous aider à être plus précis sur le type de variable attendu à différents endroits dans votre code.
C’est une fonctionnalité optionnelle en Python, qui peut être exploitée par certains IDE pour prévenir les erreurs.
Points clés
-
Python est un langage à typage dynamique.
-
Le type hinting, surtout pour les fonctions, aide à améliorer la lisibilité du code.
-
Certains outils comme
mypy
peuvent exploiter les annotations de type pour éviter des bugs potentiels. -
L’outil
pylint
peut attribuer une note à votre code.
Contenu de l’article
1 — Type hinting
Python est un langage à typage dynamique, ce qui signifie qu’il déduit le type d’une variable à partir de la valeur qui lui est assignée.
Bien que cela rende la programmation plus rapide, cela réduit la lisibilité du code.
Le Type Hinting a été introduit dans Python 3.5 pour permettre au programmeur de spécifier le type de la variable manipulée.
Ces indications purement informatives rendent le code plus facile à lire et à étendre.
Les types dits basiques sont automatiquement gérés, mais les types composés doivent être explicitement inclus.
Voici un exemple d’utilisation des annotations de type :
# Import the List type
from typing import List
# A few examples of type hinting for variables
i : int = 0
ch : str = "!"
values : List[int] = [1, 2 , 3, 4]
# An example of type hinting for functions
# Here, we indicate types of arguments and of the returned value
def my_function (a: int, b: str) -> List[float]:
...
return 0.5 * a * b
Des bibliothèques additionnelles telles que typing_extensions
ou numbers
fournissent des types supplémentaires pour le type hinting.
Vous les rencontrerez fréquemment durant ce cours.
Contrairement à Python, chaque type doit être explicite en Java, donc le type hinting n’est pas nécessaire.
Certains outils peuvent être utilisés pour exploiter les annotations de type et améliorer les performances de débogage.
Par exemple, la bibliothèque mypy
utilise les annotations de type pour détecter les erreurs de typage, comme nous le verrons ensuite.
En pratique, l’usage courant du type hinting est de l’utiliser pour les arguments de fonction et les types de retour (pour améliorer la documentation), mais pas pour toutes les variables que vous pouvez définir (bien que vous puissiez le faire).
Par exemple, vous devriez faire :
# Do not type every variable
i = 0
ch = "!"
values = [1, 2 , 3, 4]
# Still type functions
def my_function (a: int, b: str) -> List[float]:
...
return 0.5 * a * b
Mais pas :
# This makes code less readable
i : int = 0
ch : str = "!"
values : List[int] = [1, 2 , 3, 4]
# Here, an external user wants to know how to use "my_function" properly
def my_function (a, b):
...
return 0.5 * a * b
Python est un langage à typage dynamique, qui n’impose pas de typage explicite, contrairement à Java.
Ainsi, si le typage est extrêmement important dans votre cas d’application, vous pourriez préférer passer à un langage plus approprié plutôt que d’essayer de bricoler Python.
Sinon, il est préférable de suivre les pratiques de codage choisies pour le langage.
2 — Vérification de type avec MyPy
Les erreurs de type sont découvertes à l’exécution et sont parfois cachées dans des blocs conditionnels imbriqués.
mypy
est un outil utile pour vérifier la conformité des types des arguments passés à votre fonction.
mypy
exploite les annotations de type dans votre code pour vérifier la validité des valeurs passées en arguments des fonctions.
Considérons le code suivant, dans un fichier nommé distances.py
.
# Needed imports
from typing import Tuple
# Let's define a function
def euclidean_distance (point_1 : Tuple[float, float], point_2 : Tuple[float, float]) -> float:
"""
Compute the Euclidean distance between two 2D points.
In:
* point_1: The first point.
* point_2: The second point.
Out:
* The Eucldiean distance between the points.
"""
# Compute distance
return ((point_1[0] - point_2[0])**2 + (point_1[1] - point_2[1])**2)**0.5
# Ask for user input
x : int = input("x-value of pt")
y : int = input("y-value of pt")
pt : Tuple[float, float] = (x, y)
print(euclidean_distance((0, 0), pt))
Lancer la commande suivante :
python -m mypy distances.py
python -m mypy distances.py
mypy distances.py
mypy distances.py
Conduit aux erreurs suivantes indiquant clairement des problèmes de type :
distances.py:22: error: Incompatible types in assignment (expression has type "str", variable has type "int")
distances.py:23: error: Incompatible types in assignment (expression has type "str", variable has type "int")
Found 2 errors in 1 file (checked 1 source file)
3 — Évaluez votre code avec Pylint
Des outils tels que Pylint peuvent vous aider à évaluer si votre code respecte la norme Python Enhancement Proposals (PEP) 8.
Par exemple, vous pouvez lancer la commande suivante, qui donnera une note à votre code.
python -m pylint my_code.py
python -m pylint my_code.py
pylint my_code.py
pylint my_code.py
À titre d’exemple, considérez les codes Python suivants que nous avons déjà rencontrés dans le cours sur les bonnes pratiques de programmation :
m = input("Enter the message: ")
em = ""
i = 0
while (i <= len(m) - 1):
c = 1
ch = m[i]
j = i
while (j < len(m) - 1):
if (m[j] == m[j+1]):
c = c + 1
j = j + 1
else:
break
em = em + str(c) + ch
i = j + 1
print(em)
"""
This simple script encodes a message using run-length encoding.
The principle of this simple encoding is to count the number of times a character appears in a row and then append the count to the character.
Example: AAAZEEERRRR -> 3A1Z3E4R
"""
# Ask user for a string to work on
message = input("Enter the message to encode: ")
# Initialize variables
encoded_message = ""
i = 0
# Treat each character in the message
while i <= len(message) - 1:
# Count the number of times the character appears in a row
count = 1
ch = message[i]
j = i
while j < len(message) - 1 and message[j] == message[j+1]:
count = count + 1
j = j + 1
# Append the count and the character to the encoded message
encoded_message += str(count) + ch
i = j + 1
# Display the encoded message
print(encoded_message)
Lancer pylint
sur ces codes nous donne les sorties suivantes :
************* Module example
example.py:5:0: C0325: Unnecessary parens after 'while' keyword (superfluous-parens)
example.py:9:0: C0325: Unnecessary parens after 'while' keyword (superfluous-parens)
example.py:10:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens)
example.py:1:0: C0114: Missing module docstring (missing-module-docstring)
example.py:2:0: C0103: Constant name "em" doesn't conform to UPPER_CASE naming style (invalid-name)
example.py:6:4: C0103: Constant name "c" doesn't conform to UPPER_CASE naming style (invalid-name)
example.py:11:12: C0103: Constant name "c" doesn't conform to UPPER_CASE naming style (invalid-name)
------------------------------------------------------------------
Your code has been rated at 4.67/10 (previous run: 4.67/10, +0.00)
************* Module example
example.py:3:0: C0301: Line too long (144/100) (line-too-long)
example.py:11:0: C0103: Constant name "encoded_message" doesn't conform to UPPER_CASE naming style (invalid-name)
example.py:18:4: C0103: Constant name "count" doesn't conform to UPPER_CASE naming style (invalid-name)
example.py:22:8: C0103: Constant name "count" doesn't conform to UPPER_CASE naming style (invalid-name)
------------------------------------------------------------------
Your code has been rated at 6.92/10 (previous run: 5.38/10, +1.54)
Pour avoir un retour direct dans votre IDE (VSCode) concernant la conformité de votre code par rapport à la PEP8, vous pouvez installer l’extension pylint pour VSCode.
Pour aller plus loin
On dirait que cette section est vide !
Y a-t-il quelque chose que vous auriez aimé voir ici ?
Faites-le nous savoir sur le serveur Discord !
Peut-être pouvons-nous l’ajouter rapidement.
Sinon, cela nous aidera à améliorer le cours pour l’année prochaine !
Pour aller au-delà
-
La norme complète Python PEP8
-
Techniques mathématiques pour aider à l’implémentation d’un programme.
-
Outils mathématiques pour vérifier la correction d’un programme.