C’est qu’avec la prochaine version 3.4 qui apporte tellement de bonnes choses, Django 1.6 pleinement compatible et des libs comme Pillow et six pour combler les trous, ça y est, on peut enfin s’y mettre.
Commençons donc par les annotations, feature simple, et qu’on ne retrouve pas backportée en 2.7.
A rien !
Non, non, je ne déconne pas. Non seulement les annotations sont parfaitement optionnelles, mais en plus elles n’ont aucun effet.
Je répète pour que ça rentre : vous n’avez pas à utiliser les annotations. Aucun programme Python n’a besoin d’utiliser les annotations. Vous pouvez programmer votre vie entière en Python sans avoir jamais à utiliser les annotations. Et si vous les utilisez, elles ne changeront rien à votre programme.
Point.
Python est un langage très souple, et une raison de sa souplesse c’est que la nature des données que vous traitez est dynamiquement découverte à l’exécution. Particulièrement, le type des variables est dynamique. La portée des variable est dynamique.
Avantages :
Inconvénients :
C’est la nature de Python. Pour certains cas, c’est ce qu’on veut. Dans d’autres cas où ce n’est pas adapté, il faut choisir un autre langage.
Les annotations sont là pour corriger ce point : on va permettre de fournir des informations en plus, si, et seulement, si, on le souhaite.
Ces informations n’auront aucun impact sur l’exécution du code. La VM Python va les ignorer. Mais un outil extérieur pourra potentiellement les utiliser pour en faire quelque chose.
Faites chauffer votre interpréteur de Python 3…
On peut annoter uniquement les paramètres d’une fonction (ou méthode) :
>>> def ma_fonction(param1: "Une annotation", param2: 1 + 1, param3: int):
... print(param1, param2, param3)
...
>>> ma_fonction(1,2,3) # une annotation ne change absolument RIEN
1 2 3
L’annotation se note donc ainsi : nom du paramètre: annotation.
L’annotation PEUT être n’importe quelle expression Python valide. En fait l’annotation DOIT être une expression valide. Et cette expression sera exécutée une, et une seule fois, à l’initialisation du module. Le résultat sera stocké et accessible, via l’attribut __annotations__
:
>>> ma_fonction.__annotations__
{'param1': 'Une annotation', 'param2': 2, 'param3': }
Évidément, les annotations se mélangent sans problème avec les cas avancés de paramétrage :
>>> def ma_fonction(param1 : "Une annotation" = "valeur par défaut", *param2: "Autre annotation"):
... print(param1, param2)
...
>>> ma_fonction()
valeur par défaut ()
On peut également spécifier une annotation pour la valeur de retour :
>>> def ma_fonction() -> None: # un petit goût de coffeescript
... pass
...
>>> ma_fonction.__annotations__
{'return': None}
Et combiner tout ce bordel pour faire des trucs bien compliqués qui vous garantissent la sécurité d’emploi, ce qui manque cruellement en Python (les trucs compliqués, pas la sécurité d’emploi…):
>>> def ma_fonction(param1: lambda x: x * 2,
... param2: (lambda x: x * 2)(2) = 5,
... **params : "Keywords parameters rocks") -> list:
... res = [param1, param2]
... res.extend(params)
... return res
...
>>> ma_fonction(1, 2, param3=3, param4=4)
[1, 2, 'param4', 'param3']
>>> ma_fonction.__annotations__
{'return': , 'param1': at 0x7f77a2982e60>, 'param2': 4, 'params': 'Keywords parameters rocks'}
Les lambdas ne peuvent pas être annotées par contre.
Les annotations sont le cas typique d’une fonctionnalité bac à sable. En clair, sur la mailling list il y a eu de nombreuses requêtes pour permettre de la vérification de type, de l’auto documentation, de la translittération et autres joyeusetés.
Ne sachant pas comment répondre de manière propre à ces demandes, ni lesquelles étaient les plus prioritaires, les annotations ont été créées. Le but et de laisser maintenant la communauté fabriquer les outils, et ainsi :
Des outils comme pyanno donnaient déjà un exemple de ce que la communauté pouvait désirer. Reste à savoir si ce sera vraiment utilisé. Les gens qui font du Python sont rarement fan du Java. Mais le caractère optionnel de la chose pourrait bien ajouter un vrai plus au langage sans l’alourdir.
Voici donc ce qu’on peut attendre des outils tierces parties qui utiliseront les annotations dans le futur :
L’utilisation de RPython pour coder Pypy a montré que les perfs de Python pouvaient être fantastiques, si on rajoutait quelques annotations. RPython, est, je le rappelle, un subset de Python (donc tout code RPython tourne dans l’interpréteur Python normal), mais avec des annotations de type, sous forme de commentaires.
On peut donc imaginer que dans le futur, les codes en fort besoin de perfs comme pour l’embarqué ou le traitement scientifique, pourront ajouter dans les parties clés de l’algo des annotations pour booster la vitesse ou diminuer la mémoire consommée. On parlerait ici alors d’annotation de type. int
, list
, UneClasse
sont en effet des expressions Python valides…
L’avantage de l’annotation, c’est son caractère purement optionnel, qu’on peut ajouter seulement à certains codes, ou à une partie du code.
Les IDE ont du mal avec Python. La complétion du code, l’aide en popup, la refactorisation automatique et toutes ces joyeusetés sont rarement bien implémentées.
Dans ma vie de tous les jours, je m’en branle. Je code tellement vite en Python, je ne m’en aperçois même pas. Mais quand j’utilise une nouvelle lib, ça peut être utile.
Typiquement, pour un code comme celui de 0bin, je ne me servirais pas des annotations. Mais pour une lib comme minibelt, je prendrais peut être le temps de mettre des annotations de type, pour aider ceux qui vont l’utiliser. Ou une annotation pour signaler les exceptions que certaines fonctions peuvent lever.
Certains voient les annotations comme un complément aux docstrings. Ce n’est pas mon cas, mais je vous le note, au cas où ça devienne une tendance.
Dans la même lignée de l’aide à la saisie, pour certaines fonctions (c’est rare, mais ça arrive), on veut éviter le duck typing et forcer l’utilisateur à passer un type en particulier. Avoir cette possibilité via les annotations pourraient être utile.
Je suis septique sur cet usage, en effet des libs existent depuis des années pour faire cela, et plus, via des décorateurs, et ça n’est pas très utilisé. La différence est qu’un mécanisme standard pourra être détecté par les IDE.
Après on risque d’avoir des abus pour ce genre de fonctionnalités. Je vois d’ici arriver les codeurs d’autres langages caféinés, essayant de pousser l’usage d’une annotation rendant des attributs private
:-)
Heureusement, les annotations seront normalement pour toujours optionnelles.
Vous avez un code Python et vous voulez le transformer en code Cobol ? Bon, le compilateur de Pypy a déjà le potentiel de le faire, mais avec les annotations, il est potentiellement possible de rajouter suffisamment d’informations pour qu’on puisse toujours transformer un code de Python vers un autre langage Turing complet.
J’ai dit potentiellement.
Les annotations ne font rien. Elles n’ont pas le but de faire quelque chose et de toute façon sont optionnelles.
Leur but est de permettre à la communauté de créer des nouveaux outils utilisant les annotations et voir lesquels seront les plus utilisés, matures et désirés.
Pour le moment, il n’y a pas grand chose de fait avec, mais jusqu’ici Python 3 n’a pas été très populaire. Cela risque de changer avec 2014 qui propulsera Python 3.4 dans la cour des grands.
]]>