L'illusion du typage fort en Python
- Ras le bol. Ils me contactent pour des problèmes alors qu'il ne savent juste pas utiliser la lib. Je vais y rajouter des types pour éviter les pertes de temps. 😡
- Comment ça ?
- En Python, le typage est dynamique. Quand tu utilises une fonction tu ne sais pas a priori quels sont les types attendus pour les divers paramètres, d'où les erreurs. Donc il faut préciser les types. 😠
- Tu as un exemple ?
- Oui. Cette fonction qui calcule le PGCD de 2 nombres doit être appelée avec des nombres entiers
1def pgcd(p, q):
2 while q != 0:
3 p, q = q, p % q
4 return p
- Et alors ?
- Si tu l'appelles avec des nombres entiers, elle fonctionne. Par exemple, pgcd(48, 18) donne 6.
- Elle ne fonctionne pas avec des nombres à virgule qui seraient aussi des entiers ?. Par exemple, que donne pgcd(48.0, 18.0) ? 🤔
- Ça donne 6.0.
- Donc tout va bien ? 😁
- Bah non. Par exemple, 48.0+0.3-0.1-0.2, ça ne fait pas vraiment 48.0 et pgcd(48.0+0.3-0.1-0.2, 18.0), ça donne 7.105427357601002e-15. 😬
- 🤨
- C'est pour ça que je veux préciser les types. Il ne faut utiliser que des entiers.
1def pgcd(p: int, q: int) -> int:
2 while q != 0:
3 p, q = q, p % q
4 return p
[...]
- J'ai essayé ta fonction qui précise les types mais ça change rien. On peut toujours calculer pgcd(48.0+0.3-0.1-0.2, 18.0). 😐
- Oui. C'est parce que la vérification des types n'intervient pas lors de l'exécution classique mais en utilisant le programme mypy. Par exemple, avec ce programme :
1def pgcd(p: int, q: int) -> int:
2 while q != 0:
3 p, q = q, p % q
4 return p
5
6print(pgcd(48.0, 18.0))
Si j'exécute mypy vérification_pgcd.py, j'obtiens l'erreur suivante:
vérification_pgcd.py:6: error: Argument 1 to "pgcd" has incompatible type "float"; expected "int" [arg-type]
vérification_pgcd.py:6: error: Argument 2 to "pgcd" has incompatible type "float"; expected "int" [arg-type]
Found 2 errors in 1 file (checked 1 source file)
- C'est bizarre. Chez moi il n'y a pas d'erreur. 🤭
Success: no issues found in 1 source file
- Impossible. Montre moi ton code.
- Il est là. 🤪
1def pgcd(p: int, q: int) -> int:
2 while q != 0:
3 p, q = q, p % q
4 return p
5
6def affiche_pgcd(p, q):
7 print(f"PGCD = {pgcd(p, q)}")
8
9affiche_pgcd(48, 18)
10affiche_pgcd(48.0, 18.0)
- Tu as oublié de déclarer les types sur ta fonction affiche_pgcd. 😏
- Je n'ai rien oublié. Ok pour utiliser ta fonction avec les types mais tu ne vas quand même pas forcer tout le monde à faire pareil ? La base de code existante est énorme. On ne va pas prendre des semaines pour mettre des types partout !
- Bah vous continuerez à faire des erreurs.
- Et on viendra toujours te voir pour que tu nous expliques ce qui ne va pas. 😂
- Vous êtes relous. Moi je trouve des solutions. On ne peut pas utiliser un typage dynamique sans un minimum de rigueur. Le langage ne peut pas tout faire à votre place.
- Tu es sûr de ça ? Il faudrait creuser le sujet.
- 100% sûr. Ne perds pas ton temps. Mets plutôt des déclarations de type dans ton code.
- Je vais étudier la question. 🤓
[TO BE CONTINUED]